diff --git a/docs/core_docs/src/theme/SiteMetadata/index.js b/docs/core_docs/src/theme/SiteMetadata/index.js new file mode 100644 index 000000000000..e631d07277d7 --- /dev/null +++ b/docs/core_docs/src/theme/SiteMetadata/index.js @@ -0,0 +1,126 @@ +/* eslint-disable import/no-extraneous-dependencies */ +/* eslint-disable prefer-template */ +/* eslint-disable react/no-array-index-key */ + +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 ( + + {Object.entries(localeConfigs).map(([locale, { htmlLang }]) => ( + + ))} + + + ); +} +// 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 ( + + + + + ); +} +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 ( + <> + + + {/* The keyboard focus class name need to be applied when SSR so links + are outlined when JS is disabled */} + + + + {defaultImage && } + + + + + + + + {/* + It's important to have an additional element here, as it allows + react-helmet to override default metadata values set in previous + like "twitter:card". In same Head, the same meta would appear twice + instead of overriding. + */} + + {/* Yes, "metadatum" is the grammatically correct term */} + {metadata.map((metadatum, i) => ( + + ))} + + + ); +}