From 1cb730396fb61edb90df6c4d94b75c57e111f1e7 Mon Sep 17 00:00:00 2001
From: Hayden Costa <97135207+costh-netm@users.noreply.github.com>
Date: Fri, 30 Jun 2023 11:48:50 +0100
Subject: [PATCH] feat: add base as option (#81)
* Add base element as an option
* Add automatically generated api documentation
* Update e2e tests and override unit test
---
...atsby-plugin-next-seo.baseseoprops.base.md | 13 ++++++++++
.../gatsby-plugin-next-seo.baseseoprops.md | 1 +
docs/api/gatsby-plugin-next-seo.gatsbyseo.md | 2 +-
docs/etc/gatsby-plugin-next-seo.api.md | 9 ++++++-
e2e/__tests__/seo.e2e.ts | 8 +++++++
example/gatsby-config.js | 4 ++++
example/src/pages/overridden.tsx | 4 ++++
.../__snapshots__/base-seo.test.tsx.snap | 5 ++++
src/meta/__tests__/base-seo.test.tsx | 24 +++++++++++++++++++
src/meta/base-seo.tsx | 4 ++++
src/meta/gatsby-seo.tsx | 3 +++
src/types.ts | 9 +++++++
12 files changed, 84 insertions(+), 2 deletions(-)
create mode 100644 docs/api/gatsby-plugin-next-seo.baseseoprops.base.md
diff --git a/docs/api/gatsby-plugin-next-seo.baseseoprops.base.md b/docs/api/gatsby-plugin-next-seo.baseseoprops.base.md
new file mode 100644
index 0000000..3d250dd
--- /dev/null
+++ b/docs/api/gatsby-plugin-next-seo.baseseoprops.base.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [gatsby-plugin-next-seo](./gatsby-plugin-next-seo.md) > [BaseSeoProps](./gatsby-plugin-next-seo.baseseoprops.md) > [base](./gatsby-plugin-next-seo.baseseoprops.base.md)
+
+## BaseSeoProps.base property
+
+Specifies the base URL to use for all relative URLs in a document. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
+
+Signature:
+
+```typescript
+base?: BaseProps;
+```
diff --git a/docs/api/gatsby-plugin-next-seo.baseseoprops.md b/docs/api/gatsby-plugin-next-seo.baseseoprops.md
index f8e9c23..5d37c43 100644
--- a/docs/api/gatsby-plugin-next-seo.baseseoprops.md
+++ b/docs/api/gatsby-plugin-next-seo.baseseoprops.md
@@ -15,6 +15,7 @@ export interface BaseSeoProps
| Property | Type | Description |
| --- | --- | --- |
+| [base](./gatsby-plugin-next-seo.baseseoprops.base.md) | BaseProps | Specifies the base URL to use for all relative URLs in a document. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base |
| [canonical](./gatsby-plugin-next-seo.baseseoprops.canonical.md) | string | Set the page canonical url. |
| [description](./gatsby-plugin-next-seo.baseseoprops.description.md) | string | Set the page meta description. |
| [facebook](./gatsby-plugin-next-seo.baseseoprops.facebook.md) | { appId: string; } | Used for Facebook Insights, you must add a facebook app ID to your page to for it. |
diff --git a/docs/api/gatsby-plugin-next-seo.gatsbyseo.md b/docs/api/gatsby-plugin-next-seo.gatsbyseo.md
index 791bb01..2f7a8f7 100644
--- a/docs/api/gatsby-plugin-next-seo.gatsbyseo.md
+++ b/docs/api/gatsby-plugin-next-seo.gatsbyseo.md
@@ -9,7 +9,7 @@ This component render the tags in the `
` for SEO on a per page basis. As a
Signature:
```typescript
-GatsbySeo: ({ metaTags, linkTags, canonical, description, facebook, htmlAttributes, language, languageAlternates, mobileAlternate, nofollow, noindex, openGraph, title, titleTemplate, twitter, }: GatsbySeoProps) => JSX.Element
+GatsbySeo: ({ metaTags, linkTags, canonical, description, facebook, htmlAttributes, language, languageAlternates, mobileAlternate, nofollow, noindex, openGraph, title, titleTemplate, twitter, base, }: GatsbySeoProps) => JSX.Element
```
## Remarks
diff --git a/docs/etc/gatsby-plugin-next-seo.api.md b/docs/etc/gatsby-plugin-next-seo.api.md
index 16f3abf..0876855 100644
--- a/docs/etc/gatsby-plugin-next-seo.api.md
+++ b/docs/etc/gatsby-plugin-next-seo.api.md
@@ -60,11 +60,18 @@ export interface ArticleJsonLdProps extends DeferSeoProps, Overrides {
url: string;
}
+// Warning: (ae-internal-missing-underscore) The name "BaseProps" should be prefixed with an underscore because the declaration is marked as @internal
+//
+// @internal (undocumented)
+export type BaseProps = JSX.IntrinsicElements['base'];
+
// @public
export const BaseSeo: ({ defer, metaTags, linkTags, ...props }: AllSeoProps) => JSX.Element;
// @public (undocumented)
export interface BaseSeoProps {
+ // Warning: (ae-incompatible-release-tags) The symbol "base" is marked as @public, but its signature references "BaseProps" which is marked as @internal
+ base?: BaseProps;
canonical?: string;
description?: string;
facebook?: {
@@ -216,7 +223,7 @@ export interface FAQJsonLdProps extends DeferSeoProps, Overrides {
}
// @public
-export const GatsbySeo: ({ metaTags, linkTags, canonical, description, facebook, htmlAttributes, language, languageAlternates, mobileAlternate, nofollow, noindex, openGraph, title, titleTemplate, twitter, }: GatsbySeoProps) => JSX.Element;
+export const GatsbySeo: ({ metaTags, linkTags, canonical, description, facebook, htmlAttributes, language, languageAlternates, mobileAlternate, nofollow, noindex, openGraph, title, titleTemplate, twitter, base, }: GatsbySeoProps) => JSX.Element;
// @public (undocumented)
export interface GatsbySeoPluginOptions extends DefaultSeoProps, BaseSeoProps {
diff --git a/e2e/__tests__/seo.e2e.ts b/e2e/__tests__/seo.e2e.ts
index 358d761..bd6c0e5 100644
--- a/e2e/__tests__/seo.e2e.ts
+++ b/e2e/__tests__/seo.e2e.ts
@@ -9,6 +9,8 @@ test.each(testIterator)('Default SEO / - %s', async (_, disableJavascript) => {
const $document = await launch({ disableJavascript, path: '/' });
const tagAssertions = [
{ selector: 'h1', prop: 'innerText', result: 'Default SEO on this Page' },
+ { selector: 'base', prop: 'href', result: 'http://www.test.com/' },
+ { selector: 'base', prop: 'target', result: '_blank' },
{
selector: 'head title',
prop: 'innerText',
@@ -116,6 +118,12 @@ test.each(testIterator)(
const tagAssertions: TagAssertionBuilder[] = [
{ selector: 'h1', prop: 'innerText', result: 'Overridden Seo' },
+ {
+ selector: 'base',
+ prop: 'href',
+ result: 'http://www.overridetest.com/',
+ },
+ { selector: 'base', prop: 'target', result: '_self' },
{
selector: 'html',
prop: 'lang',
diff --git a/example/gatsby-config.js b/example/gatsby-config.js
index 22c47b7..8fc83c7 100644
--- a/example/gatsby-config.js
+++ b/example/gatsby-config.js
@@ -14,6 +14,10 @@ module.exports = {
{
resolve: 'gatsby-plugin-next-seo',
options: {
+ base: {
+ href: 'http://www.test.com',
+ target: '_blank',
+ },
title: 'Title A',
titleTemplate: '%s | Gatsby SEO',
description: 'Description A',
diff --git a/example/src/pages/overridden.tsx b/example/src/pages/overridden.tsx
index b5b861d..78664dc 100644
--- a/example/src/pages/overridden.tsx
+++ b/example/src/pages/overridden.tsx
@@ -9,6 +9,10 @@ const Overridden = () => (
noindex={true}
nofollow={true}
title='Title B'
+ base={{
+ href: 'http://www.overridetest.com',
+ target: '_self',
+ }}
description='Description B'
canonical='https://www.canonical.ie/b'
language='en'
diff --git a/src/meta/__tests__/__snapshots__/base-seo.test.tsx.snap b/src/meta/__tests__/__snapshots__/base-seo.test.tsx.snap
index 5fad357..61829c5 100644
--- a/src/meta/__tests__/__snapshots__/base-seo.test.tsx.snap
+++ b/src/meta/__tests__/__snapshots__/base-seo.test.tsx.snap
@@ -591,6 +591,11 @@ exports[`renders correctly 1`] = `
This is a test title.
+
{
SEO.language,
);
+ expect(document.querySelector('base')?.getAttribute('href')).toBe(
+ SEO?.base?.href,
+ );
+ expect(document.querySelector('base')?.getAttribute('target')).toBe(
+ SEO?.base?.target,
+ );
+
const title = getByText(
document.documentElement,
(content, element) =>
@@ -315,9 +326,15 @@ test('BaseSeo respects the nesting/overriding behaviour of React Helmet', () =>
const title = 'Example Title';
const exampleUrlBase = 'https://example.com';
const exampleUrlOverride = 'https://examp2le.com';
+ const exampleBaseHrefOverride = 'https://overridetest.com';
+ const exampleBaseTargetOverride = '_self';
render(
<>
);
expect(ogUrlTag).toBeTruthy();
expect(ogUrlTag?.getAttribute('content')).toEqual(exampleUrlOverride);
+
+ expect(document.querySelector('base')?.getAttribute('href')).toBe(
+ exampleBaseHrefOverride,
+ );
+ expect(document.querySelector('base')?.getAttribute('target')).toBe(
+ exampleBaseTargetOverride,
+ );
});
const ArticleSEO = {
diff --git a/src/meta/base-seo.tsx b/src/meta/base-seo.tsx
index 6c628a7..100dab9 100644
--- a/src/meta/base-seo.tsx
+++ b/src/meta/base-seo.tsx
@@ -479,6 +479,10 @@ export const BaseSeo = ({
helmetProps['titleTemplate'] = props.titleTemplate;
}
+ if (props.base) {
+ helmetProps['base'] = props.base;
+ }
+
return (
<>
diff --git a/src/meta/gatsby-seo.tsx b/src/meta/gatsby-seo.tsx
index 5c8fb44..74a1ca0 100644
--- a/src/meta/gatsby-seo.tsx
+++ b/src/meta/gatsby-seo.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import React from 'react';
import { GatsbySeoProps } from '../types';
@@ -39,6 +40,7 @@ export const GatsbySeo = ({
title,
titleTemplate,
twitter,
+ base,
}: GatsbySeoProps) => {
return (
);
};
diff --git a/src/types.ts b/src/types.ts
index 03ca5d1..3fd1a1d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -244,6 +244,11 @@ interface HTMLAttributes {
* @public
*/
export interface BaseSeoProps {
+ /**
+ * Specifies the base URL to use for all relative URLs in a document. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
+ */
+ base?: BaseProps;
+
/**
* The language being used for the current page.
*
@@ -592,3 +597,7 @@ export type StyleProps = JSX.IntrinsicElements['style'];
* @internal
*/
export type TitleProps = JSX.IntrinsicElements['title'];
+/**
+ * @internal
+ */
+export type BaseProps = JSX.IntrinsicElements['base'];