diff --git a/__tests__/api/base.test.tsx b/__tests__/api/base.test.tsx index e962e4a7..34953a9a 100644 --- a/__tests__/api/base.test.tsx +++ b/__tests__/api/base.test.tsx @@ -30,8 +30,21 @@ describe('base tag', () => { expect(existingTags).toHaveLength(0); }); - it('tags without \'href\' are not accepted', () => { - renderClient(); + it("tags with only 'target' are accepted", () => { + renderClient(); + const existingTags = [...document.head.querySelectorAll(`base[${HELMET_ATTRIBUTE}]`)]; + + expect(existingTags).toBeDefined(); + expect(existingTags).toHaveLength(1); + const firstTag = existingTags[0]!; + expect(firstTag).toBeInstanceOf(Element); + expect(firstTag.getAttribute).toBeDefined(); + expect(firstTag).toHaveAttribute('target', '_blank'); + expect(firstTag).not.toHaveAttribute('href'); + }); + + it("tags without 'href' or 'target' are not accepted", () => { + renderClient(); const existingTags = document.head.querySelectorAll(`base[${HELMET_ATTRIBUTE}]`); expect(existingTags).toBeDefined(); @@ -97,7 +110,25 @@ describe('base tag', () => { expect(existingTags).toHaveLength(0); }); - it('tags without \'href\' are not accepted', () => { + it("tags with only 'target' are accepted", () => { + renderClient( + + + , + ); + + const existingTags = [...document.head.querySelectorAll(`base[${HELMET_ATTRIBUTE}]`)]; + + expect(existingTags).toBeDefined(); + expect(existingTags).toHaveLength(1); + const firstTag = existingTags[0]!; + expect(firstTag).toBeInstanceOf(Element); + expect(firstTag.getAttribute).toBeDefined(); + expect(firstTag).toHaveAttribute('target', '_blank'); + expect(firstTag).not.toHaveAttribute('href'); + }); + + it("tags without 'href' or 'target' are not accepted", () => { /* eslint-disable react/no-unknown-property */ renderClient( diff --git a/__tests__/server/base.test.tsx b/__tests__/server/base.test.tsx index 8ffd818e..7deede99 100644 --- a/__tests__/server/base.test.tsx +++ b/__tests__/server/base.test.tsx @@ -35,6 +35,30 @@ describe('server', () => { expect(head?.base.toString).toBeDefined(); expect(head?.base.toString()).toMatchSnapshot(); }); + + it("renders base tag with only 'target' as React component", () => { + const head = renderContextServer(); + + expect(head?.base).toBeDefined(); + expect(head?.base.toComponent).toBeDefined(); + + const baseComponent = head?.base.toComponent(); + + expect(baseComponent).toStrictEqual(isArray); + expect(baseComponent).toHaveLength(1); + + const markup = renderToStaticMarkup(baseComponent); + expect(markup).toContain('target="_blank"'); + expect(markup).not.toContain('href='); + }); + + it("renders base tag with only 'target' as string", () => { + const head = renderContextServer(); + expect(head?.base).toBeDefined(); + expect(head?.base.toString).toBeDefined(); + expect(head?.base.toString()).toContain('target="_blank"'); + expect(head?.base.toString()).not.toContain('href='); + }); }); describe('Declarative API', () => { @@ -73,5 +97,39 @@ describe('server', () => { expect(head!.base.toString).toBeDefined(); expect(head?.base.toString()).toMatchSnapshot(); }); + + it("renders base tag with only 'target' as React component", () => { + const head = renderContextServer( + + + , + ); + + expect(head?.base).toBeDefined(); + expect(head?.base.toComponent).toBeDefined(); + + const baseComponent = head?.base.toComponent(); + + expect(baseComponent).toStrictEqual(isArray); + expect(baseComponent).toHaveLength(1); + + const markup = renderToStaticMarkup(baseComponent); + + expect(markup).toContain('target="_blank"'); + expect(markup).not.toContain('href='); + }); + + it("renders base tag with only 'target' as string", () => { + const head = renderContextServer( + + + , + ); + + expect(head?.base).toBeDefined(); + expect(head?.base.toString).toBeDefined(); + expect(head?.base.toString()).toContain('target="_blank"'); + expect(head?.base.toString()).not.toContain('href='); + }); }); }); diff --git a/src/constants.ts b/src/constants.ts index e7106020..d56e6b29 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,6 +9,7 @@ export enum TAG_PROPERTIES { PROPERTY = 'property', REL = 'rel', SRC = 'src', + TARGET = 'target', } export enum ATTRIBUTE_NAMES { diff --git a/src/utils.ts b/src/utils.ts index 7e638fa7..8c6e8326 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -103,7 +103,7 @@ export function aggregateBaseProps( ): BaseProps | undefined { for (let i = props.length - 1; i >= 0; --i) { const res = props[i]![1].base; - if (res?.href) return res; + if (res?.href || res?.target) return res; } return undefined; }