diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap index e042c366581d..29dd570e2366 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap @@ -86,6 +86,9 @@ exports[`DefaultSidebarItemsGenerator generates simple flat sidebar 1`] = ` "type": "doc", }, { + "customProps": { + "custom": "prop", + }, "id": "doc1", "label": "doc1 sidebar label", "type": "doc", diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts index 43e40938df0e..f8fb292874c2 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts @@ -64,6 +64,7 @@ describe('DefaultSidebarItemsGenerator', () => { sidebarPosition: 2, frontMatter: { sidebar_label: 'doc1 sidebar label', + sidebar_custom_props: {custom: 'prop'}, }, title: '', unversionedId: 'doc1', diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts index 7dc6ece7bedc..5a6b325449b1 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts @@ -138,7 +138,11 @@ Available doc IDs: ): WithPosition { const { sidebarPosition: position, - frontMatter: {sidebar_label: label, sidebar_class_name: className}, + frontMatter: { + sidebar_label: label, + sidebar_class_name: className, + sidebar_custom_props: customProps, + }, } = getDoc(id); return { type: 'doc', @@ -149,6 +153,7 @@ Available doc IDs: // sidebar ...(label !== undefined && {label}), ...(className !== undefined && {className}), + ...(customProps !== undefined && {customProps}), }; } function createCategoryItem( diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Container/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Container/index.tsx index ab9d2a986933..0cfb6b336fe5 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Container/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Container/index.tsx @@ -14,17 +14,26 @@ export default function BlogPostItemContainer({ children, className, }: Props): JSX.Element { - const {frontMatter, assets} = useBlogPost(); + const { + frontMatter, + assets, + metadata: {description}, + } = useBlogPost(); const {withBaseUrl} = useBaseUrlUtils(); const image = assets.image ?? frontMatter.image; + const keywords = frontMatter.keywords ?? []; return (
+ {description && } {image && ( - + + )} + {keywords.length > 0 && ( + )} {children}
diff --git a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx index 92ace43f3220..5f2eb1d7be38 100644 --- a/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/BlogPostItem/Header/Author/index.tsx @@ -28,7 +28,12 @@ export default function BlogPostItemHeaderAuthor({
{imageURL && ( - {name} + {name} )} diff --git a/packages/docusaurus-theme-classic/src/theme/DocPage/Layout/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocPage/Layout/styles.module.css index 3cc2c95bdd7f..e5435c64edd7 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPage/Layout/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocPage/Layout/styles.module.css @@ -15,3 +15,11 @@ display: flex; flex: 1 0 auto; } + +/* +JS disabled??? Show light version by default => better than showing nothing +TODO bad, but we currently always show light mode when there's no data-theme + */ +html:not([data-theme]) .themedComponent--light { + display: initial; +} diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx index d426298f6a8d..4c76343602b9 100644 --- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/Ul/index.tsx @@ -11,7 +11,11 @@ import type {Props} from '@theme/MDXComponents/Ul'; import styles from './styles.module.css'; -function transformUlClassName(className?: string): string { +function transformUlClassName(className?: string): string | undefined { + // Fix https://github.com/facebook/docusaurus/issues/9098 + if (typeof className === 'undefined') { + return undefined; + } return clsx( className, // This class is set globally by GitHub/MDX. We keep the global class, and diff --git a/packages/docusaurus-theme-classic/src/theme/SiteMetadata/index.tsx b/packages/docusaurus-theme-classic/src/theme/SiteMetadata/index.tsx index 9a30c775fff2..4a275e819c17 100644 --- a/packages/docusaurus-theme-classic/src/theme/SiteMetadata/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/SiteMetadata/index.tsx @@ -16,6 +16,7 @@ import { 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 ? @@ -58,10 +59,19 @@ function AlternateLangHeaders(): JSX.Element { // Default canonical url inferred from current page location pathname function useDefaultCanonicalUrl() { const { - siteConfig: {url: siteUrl}, + 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(); - return siteUrl + useBaseUrl(pathname); + + const canonicalPathname = applyTrailingSlash(useBaseUrl(pathname), { + trailingSlash, + baseUrl, + }); + + return siteUrl + canonicalPathname; } // TODO move to SiteMetadataDefaults or theme-common ? diff --git a/packages/docusaurus-theme-common/src/utils/useAlternatePageUtils.ts b/packages/docusaurus-theme-common/src/utils/useAlternatePageUtils.ts index ae0e55dcddff..073aa8956f3b 100644 --- a/packages/docusaurus-theme-common/src/utils/useAlternatePageUtils.ts +++ b/packages/docusaurus-theme-common/src/utils/useAlternatePageUtils.ts @@ -7,6 +7,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import {useLocation} from '@docusaurus/router'; +import {applyTrailingSlash} from '@docusaurus/utils-common'; /** * Permits to obtain the url of the current page in another locale, useful to @@ -35,17 +36,25 @@ export function useAlternatePageUtils(): { }) => string; } { const { - siteConfig: {baseUrl, url}, + siteConfig: {baseUrl, url, trailingSlash}, i18n: {defaultLocale, currentLocale}, } = useDocusaurusContext(); + + // TODO using useLocation().pathname is not a super idea + // See https://github.com/facebook/docusaurus/issues/9170 const {pathname} = useLocation(); + const canonicalPathname = applyTrailingSlash(pathname, { + trailingSlash, + baseUrl, + }); + const baseUrlUnlocalized = currentLocale === defaultLocale ? baseUrl : baseUrl.replace(`/${currentLocale}/`, '/'); - const pathnameSuffix = pathname.replace(baseUrl, ''); + const pathnameSuffix = canonicalPathname.replace(baseUrl, ''); function getLocalizedBaseUrl(locale: string) { return locale === defaultLocale diff --git a/packages/docusaurus/src/client/App.tsx b/packages/docusaurus/src/client/App.tsx index 8554f5b91aec..3a93ec6524a8 100644 --- a/packages/docusaurus/src/client/App.tsx +++ b/packages/docusaurus/src/client/App.tsx @@ -23,6 +23,7 @@ import SiteMetadataDefaults from './SiteMetadataDefaults'; // TODO, quick fix for CSS insertion order // eslint-disable-next-line import/order import ErrorBoundary from '@docusaurus/ErrorBoundary'; +import HasHydratedDataAttribute from './hasHydratedDataAttribute'; export default function App(): JSX.Element { const routeElement = renderRoutes(routes); @@ -39,6 +40,7 @@ export default function App(): JSX.Element { {routeElement} + diff --git a/packages/docusaurus/src/client/hasHydratedDataAttribute.tsx b/packages/docusaurus/src/client/hasHydratedDataAttribute.tsx new file mode 100644 index 000000000000..1855f059775e --- /dev/null +++ b/packages/docusaurus/src/client/hasHydratedDataAttribute.tsx @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import Head from '@docusaurus/Head'; +import useIsBrowser from '@docusaurus/useIsBrowser'; + +// See https://github.com/facebook/docusaurus/pull/9256 +// Docusaurus adds a after hydration +export default function HasHydratedDataAttribute(): JSX.Element { + const isBrowser = useIsBrowser(); + return ( + + + + ); +}