diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index 11b6fb649946..2daea9fe1272 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -163,6 +163,7 @@ describe('simple website', () => { source: path.join('@site', pluginPath, 'hello.md'), title: 'Hello, World !', description: 'Hi, Endilie here :)', + latestVersionMainDocPermalink: undefined, }); expect(docsMetadata['foo/bar']).toEqual({ @@ -176,6 +177,7 @@ describe('simple website', () => { source: path.join('@site', pluginPath, 'foo', 'bar.md'), title: 'Bar', description: 'This is custom description', + latestVersionMainDocPermalink: undefined, }); expect(docsSidebars).toMatchSnapshot(); @@ -335,6 +337,7 @@ describe('versioned website', () => { title: 'bar', permalink: '/docs/foo/bar', }, + latestVersionMainDocPermalink: undefined, }); expect(docsMetadata['version-1.0.0/foo/baz']).toEqual({ id: 'version-1.0.0/foo/baz', diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/metadata.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/metadata.test.ts index d54dbd8f33a0..17759bff68ab 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/metadata.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/metadata.test.ts @@ -50,6 +50,7 @@ describe('simple site', () => { source: path.join('@site', routeBasePath, sourceA), title: 'Bar', description: 'This is custom description', + latestVersionMainDocPermalink: undefined, }); expect(dataB).toEqual({ id: 'hello', @@ -57,6 +58,7 @@ describe('simple site', () => { source: path.join('@site', routeBasePath, sourceB), title: 'Hello, World !', description: `Hi, Endilie here :)`, + latestVersionMainDocPermalink: undefined, }); }); @@ -85,6 +87,7 @@ describe('simple site', () => { editUrl: 'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md', description: 'Images', + latestVersionMainDocPermalink: undefined, }); }); @@ -109,6 +112,7 @@ describe('simple site', () => { title: 'lorem', editUrl: 'https://github.com/customUrl/docs/lorem.md', description: 'Lorem ipsum.', + latestVersionMainDocPermalink: undefined, }); // unrelated frontmatter is not part of metadata @@ -140,6 +144,7 @@ describe('simple site', () => { description: 'Lorem ipsum.', lastUpdatedAt: 1539502055, lastUpdatedBy: 'Author', + latestVersionMainDocPermalink: undefined, }); }); @@ -168,6 +173,7 @@ describe('simple site', () => { description: 'Lorem ipsum.', lastUpdatedAt: 1539502055, lastUpdatedBy: 'Author', + latestVersionMainDocPermalink: undefined, }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index 4459e295e573..614abda44bc9 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -65,6 +65,22 @@ const DEFAULT_OPTIONS: PluginOptions = { admonitions: {}, }; +function getFirstDocLinkOfSidebar( + sidebarItems: DocsSidebarItem[], +): string | null { + for (let sidebarItem of sidebarItems) { + if (sidebarItem.type === 'category') { + const url = getFirstDocLinkOfSidebar(sidebarItem.items); + if (url) { + return url; + } + } else { + return sidebarItem.href; + } + } + return null; +} + export default function pluginContentDocs( context: LoadContext, opts: Partial, @@ -320,7 +336,6 @@ Available document ids= }, {}, ); - return { docsMetadata, docsDir, @@ -368,7 +383,6 @@ Available document ids= const isDocsHomePage = metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') === options.homePageId; - if (isDocsHomePage) { const versionDocsPathPrefix = (metadataItem?.version === versioning.latestVersion @@ -384,6 +398,7 @@ Available document ids= homePageDocsRoutePath, versionDocsPathPrefix, ]); + const docsBaseMetadataPath = await createData( `${docuHash(metadataItem.source)}-base.json`, JSON.stringify(docsBaseMetadata, null, 2), @@ -461,6 +476,22 @@ Available document ids= Object.values(content.docsMetadata), 'version', ); + const rootUrl = + options.homePageId && content.docsMetadata[options.homePageId] + ? normalizeUrl([baseUrl, routeBasePath]) + : getFirstDocLinkOfSidebar( + content.docsSidebars[ + `version-${versioning.latestVersion}/docs` + ], + ); + if (!rootUrl) { + throw new Error('Bad sidebars file. No document linked'); + } + Object.values(content.docsMetadata).forEach((docMetadata) => { + if (docMetadata.version !== versioning.latestVersion) { + docMetadata.latestVersionMainDocPermalink = rootUrl; + } + }); await Promise.all( Object.keys(docsMetadataByVersion).map(async (version) => { const routes: RouteConfig[] = await genRoutes( diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index d9c4608bbdeb..2b7b8b89a295 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -118,6 +118,7 @@ export interface MetadataRaw extends LastUpdateData { sidebar_label?: string; editUrl?: string; version?: string; + latestVersionMainDocPermalink?: string; } export interface Paginator { diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js index 8d0c4c880f84..655747f999f1 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js @@ -12,6 +12,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useBaseUrl from '@docusaurus/useBaseUrl'; import DocPaginator from '@theme/DocPaginator'; import useTOCHighlight from '@theme/hooks/useTOCHighlight'; +import Link from '@docusaurus/Link'; import clsx from 'clsx'; import styles from './styles.module.css'; @@ -68,6 +69,7 @@ function DocItem(props) { lastUpdatedAt, lastUpdatedBy, version, + latestVersionMainDocPermalink, } = metadata; const { frontMatter: { @@ -108,6 +110,33 @@ function DocItem(props) { className={clsx('col', { [styles.docItemCol]: !hideTableOfContents, })}> + {latestVersionMainDocPermalink && ( +
+ {version === 'next' ? ( +
+ This is unreleased documentation for {siteTitle}{' '} + {version} version. +
+ ) : ( +
+ This is archived documentation for {siteTitle}{' '} + v{version}, which is no longer actively + maintained. +
+ )} +
+ For up-to-date documentation, see the{' '} + + + latest version + + + . +
+
+ )}
{version && (