Skip to content

Commit

Permalink
docs: v0.2 canonical (#26514)
Browse files Browse the repository at this point in the history
  • Loading branch information
efriis authored Sep 16, 2024
1 parent cfd11b2 commit 7d2753f
Showing 1 changed file with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions docs/src/theme/SiteMetadata/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React from 'react';
import Head from '@docusaurus/Head';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useBaseUrl from '@docusaurus/useBaseUrl';
import {PageMetadata, useThemeConfig} from '@docusaurus/theme-common';
import {
DEFAULT_SEARCH_TAG,
useAlternatePageUtils,
keyboardFocusedClassName,
} from '@docusaurus/theme-common/internal';
import {useLocation} from '@docusaurus/router';
import {applyTrailingSlash} from '@docusaurus/utils-common';
import SearchMetadata from '@theme/SearchMetadata';
// TODO move to SiteMetadataDefaults or theme-common ?
// Useful for i18n/SEO
// See https://developers.google.com/search/docs/advanced/crawling/localized-versions
// See https://github.com/facebook/docusaurus/issues/3317
function AlternateLangHeaders() {
const {
i18n: {defaultLocale, localeConfigs},
} = useDocusaurusContext();
const alternatePageUtils = useAlternatePageUtils();
// Note: it is fine to use both "x-default" and "en" to target the same url
// See https://www.searchviu.com/en/multiple-hreflang-tags-one-url/
return (
<Head>
{Object.entries(localeConfigs).map(([locale, {htmlLang}]) => (
<link
key={locale}
rel="alternate"
href={alternatePageUtils.createUrl({
locale,
fullyQualified: true,
})}
hrefLang={htmlLang}
/>
))}
<link
rel="alternate"
href={alternatePageUtils.createUrl({
locale: defaultLocale,
fullyQualified: true,
})}
hrefLang="x-default"
/>
</Head>
);
}
// Default canonical url inferred from current page location pathname
function useDefaultCanonicalUrl() {
const {
siteConfig: {url: siteUrl, baseUrl, trailingSlash},
} = useDocusaurusContext();
// TODO using useLocation().pathname is not a super idea
// See https://github.com/facebook/docusaurus/issues/9170
const {pathname} = useLocation();
const baseUrlPathname = useBaseUrl(pathname);
const canonicalPathname = applyTrailingSlash(baseUrlPathname, {
trailingSlash,
baseUrl,
});
const canonicalPathnameNoVersion = canonicalPathname.startsWith('/v0.') ? "/"+canonicalPathname.split('/').slice(2).join('/') : canonicalPathname;
return siteUrl + canonicalPathnameNoVersion;
}

// TODO move to SiteMetadataDefaults or theme-common ?
function CanonicalUrlHeaders({permalink}) {
const {
siteConfig: {url: siteUrl},
} = useDocusaurusContext();
const defaultCanonicalUrl = useDefaultCanonicalUrl();
const canonicalUrl = permalink
? `${siteUrl}${permalink}`
: defaultCanonicalUrl;
return (
<Head>
<meta property="og:url" content={canonicalUrl} />
<link rel="canonical" href={canonicalUrl} />
</Head>
);
}
export default function SiteMetadata() {
const {
i18n: {currentLocale},
} = useDocusaurusContext();
// TODO maybe move these 2 themeConfig to siteConfig?
// These seems useful for other themes as well
const {metadata, image: defaultImage} = useThemeConfig();
return (
<>
<Head>
<meta name="twitter:card" content="summary_large_image" />
{/* The keyboard focus class name need to be applied when SSR so links
are outlined when JS is disabled */}
<body className={keyboardFocusedClassName} />
</Head>

{defaultImage && <PageMetadata image={defaultImage} />}

<CanonicalUrlHeaders />

<AlternateLangHeaders />

<SearchMetadata tag={DEFAULT_SEARCH_TAG} locale={currentLocale} />

{/*
It's important to have an additional <Head> element here, as it allows
react-helmet to override default metadata values set in previous <Head>
like "twitter:card". In same Head, the same meta would appear twice
instead of overriding.
*/}
<Head>
{/* Yes, "metadatum" is the grammatically correct term */}
{metadata.map((metadatum, i) => (
<meta key={i} {...metadatum} />
))}
</Head>
</>
);
}

0 comments on commit 7d2753f

Please sign in to comment.