diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap index 8a93f780e5..930280378e 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/__snapshots__/index.test.ts.snap @@ -290,6 +290,7 @@ Object { }", "version-current-metadata-prop-751.json": "{ \\"version\\": \\"current\\", + \\"label\\": \\"Next\\", \\"docsSidebars\\": { \\"docs\\": [ { @@ -613,6 +614,7 @@ Object { }", "version-1-0-0-metadata-prop-608.json": "{ \\"version\\": \\"1.0.0\\", + \\"label\\": \\"1.0.0\\", \\"docsSidebars\\": { \\"version-1.0.0/community\\": [ { @@ -628,6 +630,7 @@ Object { }", "version-current-metadata-prop-751.json": "{ \\"version\\": \\"current\\", + \\"label\\": \\"Next\\", \\"docsSidebars\\": { \\"community\\": [ { @@ -1069,6 +1072,7 @@ Object { }", "version-1-0-0-metadata-prop-608.json": "{ \\"version\\": \\"1.0.0\\", + \\"label\\": \\"1.0.0\\", \\"docsSidebars\\": { \\"version-1.0.0/docs\\": [ { @@ -1110,6 +1114,7 @@ Object { }", "version-1-0-1-metadata-prop-e87.json": "{ \\"version\\": \\"1.0.1\\", + \\"label\\": \\"1.0.1\\", \\"docsSidebars\\": { \\"version-1.0.1/docs\\": [ { @@ -1145,6 +1150,7 @@ Object { }", "version-current-metadata-prop-751.json": "{ \\"version\\": \\"current\\", + \\"label\\": \\"Next\\", \\"docsSidebars\\": { \\"docs\\": [ { @@ -1180,6 +1186,7 @@ Object { }", "version-with-slugs-metadata-prop-2bf.json": "{ \\"version\\": \\"withSlugs\\", + \\"label\\": \\"withSlugs\\", \\"docsSidebars\\": { \\"version-1.0.1/docs\\": [ { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index df1028a97f..6069563640 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -135,21 +135,23 @@ describe('simple site', () => { test('readVersionDocs', async () => { const docs = await readVersionDocs(currentVersion, options); - expect(docs.map((doc) => doc.source)).toMatchObject([ - 'hello.md', - 'ipsum.md', - 'lorem.md', - 'rootAbsoluteSlug.md', - 'rootRelativeSlug.md', - 'rootResolvedSlug.md', - 'rootTryToEscapeSlug.md', - 'foo/bar.md', - 'foo/baz.md', - 'slugs/absoluteSlug.md', - 'slugs/relativeSlug.md', - 'slugs/resolvedSlug.md', - 'slugs/tryToEscapeSlug.md', - ]); + expect(docs.map((doc) => doc.source).sort()).toEqual( + [ + 'hello.md', + 'ipsum.md', + 'lorem.md', + 'rootAbsoluteSlug.md', + 'rootRelativeSlug.md', + 'rootResolvedSlug.md', + 'rootTryToEscapeSlug.md', + 'foo/bar.md', + 'foo/baz.md', + 'slugs/absoluteSlug.md', + 'slugs/relativeSlug.md', + 'slugs/resolvedSlug.md', + 'slugs/tryToEscapeSlug.md', + ].sort(), + ); }); test('normal docs', async () => { diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts index d065896f1c..9b0052df75 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/options.test.ts @@ -36,6 +36,16 @@ describe('normalizeDocsPluginOptions', () => { excludeNextVersionDocs: true, includeCurrentVersion: false, disableVersioning: true, + versions: { + current: { + path: 'next', + label: 'next', + }, + version1: { + path: 'hello', + label: 'world', + }, + }, }; const {value, error} = await OptionsSchema.validate(userOptions); expect(value).toEqual(userOptions); @@ -117,4 +127,32 @@ describe('normalizeDocsPluginOptions', () => { `"\\"remarkPlugins\\" must be an array"`, ); }); + + test('should reject bad lastVersion', () => { + expect(() => { + normalizePluginOptions(OptionsSchema, { + lastVersion: false, + }); + }).toThrowErrorMatchingInlineSnapshot( + `"\\"lastVersion\\" must be a string"`, + ); + }); + + test('should reject bad versions', () => { + expect(() => { + normalizePluginOptions(OptionsSchema, { + versions: { + current: { + hey: 3, + }, + version1: { + path: 'hello', + label: 'world', + }, + }, + }); + }).toThrowErrorMatchingInlineSnapshot( + `"\\"versions.current.hey\\" is not allowed"`, + ); + }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts index bba60d89f2..c8c2f1cb35 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts @@ -94,7 +94,63 @@ describe('simple site', () => { ]); }); - test('readVersionsMetadata simple site with base url', () => { + test('readVersionsMetadata simple site with current version config', () => { + const versionsMetadata = readVersionsMetadata({ + options: { + ...defaultOptions, + versions: { + current: { + label: 'current-label', + path: 'current-path', + }, + }, + }, + context: { + ...defaultContext, + baseUrl: '/myBaseUrl', + }, + }); + + expect(versionsMetadata).toEqual([ + { + ...vCurrent, + versionPath: '/myBaseUrl/docs/current-path', + versionLabel: 'current-label', + routePriority: undefined, + }, + ]); + }); + + test('readVersionsMetadata simple site with unknown lastVersion should throw', () => { + expect(() => + readVersionsMetadata({ + options: {...defaultOptions, lastVersion: 'unknownVersionName'}, + context: defaultContext, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Docs option lastVersion=unknownVersionName is invalid. Available version names are: current"`, + ); + }); + + test('readVersionsMetadata simple site with unknown version configurations should throw', () => { + expect(() => + readVersionsMetadata({ + options: { + ...defaultOptions, + versions: { + current: {label: 'current'}, + unknownVersionName1: {label: 'unknownVersionName1'}, + unknownVersionName2: {label: 'unknownVersionName2'}, + }, + }, + context: defaultContext, + }), + ).toThrowErrorMatchingInlineSnapshot( + `"Docs versions option provided configuration for unknown versions: unknownVersionName1,unknownVersionName2. Available version names are: current"`, + ); + }); + + test('readVersionsMetadata simple site with disableVersioning while single version should throw', () => { expect(() => readVersionsMetadata({ options: {...defaultOptions, disableVersioning: true}, @@ -105,7 +161,7 @@ describe('simple site', () => { ); }); - test('readVersionsMetadata simple site with base url', () => { + test('readVersionsMetadata simple site without including current version should throw', () => { expect(() => readVersionsMetadata({ options: {...defaultOptions, includeCurrentVersion: false}, @@ -205,6 +261,42 @@ describe('versioned site, pluginId=default', () => { ]); }); + test('readVersionsMetadata versioned site with version options', () => { + const versionsMetadata = readVersionsMetadata({ + options: { + ...defaultOptions, + lastVersion: '1.0.0', + versions: { + current: { + path: 'current-path', + }, + '1.0.0': { + label: '1.0.0-label', + }, + }, + }, + context: defaultContext, + }); + + expect(versionsMetadata).toEqual([ + {...vCurrent, versionPath: '/docs/current-path'}, + { + ...v101, + isLast: false, + routePriority: undefined, + versionPath: '/docs/1.0.1', + }, + { + ...v100, + isLast: true, + routePriority: -1, + versionLabel: '1.0.0-label', + versionPath: '/docs', + }, + vwithSlugs, + ]); + }); + test('readVersionsMetadata versioned site with disableVersioning', () => { const versionsMetadata = readVersionsMetadata({ options: {...defaultOptions, disableVersioning: true}, diff --git a/packages/docusaurus-plugin-content-docs/src/options.ts b/packages/docusaurus-plugin-content-docs/src/options.ts index e036651dd7..867a69d9e9 100644 --- a/packages/docusaurus-plugin-content-docs/src/options.ts +++ b/packages/docusaurus-plugin-content-docs/src/options.ts @@ -33,8 +33,19 @@ export const DEFAULT_OPTIONS: Omit = { excludeNextVersionDocs: false, includeCurrentVersion: true, disableVersioning: false, + lastVersion: undefined, + versions: {}, }; +const VersionOptionsSchema = Joi.object({ + path: Joi.string().allow('').optional(), + label: Joi.string().optional(), +}); + +const VersionsOptionsSchema = Joi.object() + .pattern(Joi.string().required(), VersionOptionsSchema) + .default(DEFAULT_OPTIONS.versions); + export const OptionsSchema = Joi.object({ path: Joi.string().default(DEFAULT_OPTIONS.path), editUrl: URISchema, @@ -58,6 +69,8 @@ export const OptionsSchema = Joi.object({ DEFAULT_OPTIONS.includeCurrentVersion, ), disableVersioning: Joi.bool().default(DEFAULT_OPTIONS.disableVersioning), + lastVersion: Joi.string().optional(), + versions: VersionsOptionsSchema, }); // TODO bad validation function types diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 9cfb7eb16d..ac38232034 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -8,14 +8,13 @@ /* eslint-disable camelcase */ declare module '@docusaurus/plugin-content-docs-types' { - export type VersionName = string; - export type PermalinkToSidebar = { [permalink: string]: string; }; export type PropVersionMetadata = { - version: VersionName; + version: string; + label: string; docsSidebars: PropSidebars; permalinkToSidebar: PermalinkToSidebar; }; diff --git a/packages/docusaurus-plugin-content-docs/src/props.ts b/packages/docusaurus-plugin-content-docs/src/props.ts index 2715ba9a1b..6f758a317f 100644 --- a/packages/docusaurus-plugin-content-docs/src/props.ts +++ b/packages/docusaurus-plugin-content-docs/src/props.ts @@ -66,6 +66,7 @@ export function toVersionMetadataProp( ): PropVersionMetadata { return { version: loadedVersion.versionName, + label: loadedVersion.versionLabel, docsSidebars: toSidebarsProp(loadedVersion), permalinkToSidebar: loadedVersion.permalinkToSidebar, }; diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index a7c53edfad..fbb0b95930 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -39,8 +39,19 @@ export type PathOptions = { sidebarPath: string; }; +export type VersionOptions = { + path?: string; + label?: string; +}; + +export type VersionsOptions = { + lastVersion?: string; + versions: Record; +}; + export type PluginOptions = MetadataOptions & - PathOptions & { + PathOptions & + VersionsOptions & { id: string; include: string[]; docLayoutComponent: string; diff --git a/packages/docusaurus-plugin-content-docs/src/versions.ts b/packages/docusaurus-plugin-content-docs/src/versions.ts index cc61ab3b30..04e3a19c00 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions.ts @@ -7,7 +7,12 @@ import path from 'path'; import fs from 'fs-extra'; -import {PluginOptions, VersionMetadata} from './types'; +import { + PluginOptions, + VersionMetadata, + VersionOptions, + VersionsOptions, +} from './types'; import { VERSIONS_JSON_FILE, VERSIONED_DOCS_DIR, @@ -18,6 +23,7 @@ import { import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants'; import {LoadContext} from '@docusaurus/types'; import {normalizeUrl} from '@docusaurus/utils'; +import {difference} from 'lodash'; // retro-compatibility: no prefix for the default plugin id function addPluginIdPrefix(fileOrDir: string, pluginId: string): string { @@ -161,7 +167,10 @@ function createVersionMetadata({ versionName: string; isLast: boolean; context: Pick; - options: Pick; + options: Pick< + PluginOptions, + 'id' | 'path' | 'sidebarPath' | 'routeBasePath' | 'versions' + >; }): VersionMetadata { const {sidebarFilePath, docsDirPath} = getVersionMetadataPaths({ versionName, @@ -169,16 +178,20 @@ function createVersionMetadata({ options, }); - // TODO hardcoded for retro-compatibility - // TODO Need to make this configurable - const versionLabel = + // retro-compatible values + const defaultVersionLabel = versionName === CURRENT_VERSION_NAME ? 'Next' : versionName; - const versionPathPart = isLast + const defaultVersionPathPart = isLast ? '' : versionName === CURRENT_VERSION_NAME ? 'next' : versionName; + const versionOptions: VersionOptions = options.versions[versionName] ?? {}; + + const versionLabel = versionOptions.label ?? defaultVersionLabel; + const versionPathPart = versionOptions.path ?? defaultVersionPathPart; + const versionPath = normalizeUrl([ context.baseUrl, options.routeBasePath, @@ -219,7 +232,7 @@ function checkVersionMetadataPaths({ // TODO for retrocompatibility with existing behavior // We should make this configurable // "last version" is not a very good concept nor api surface -function getLastVersionName(versionNames: string[]) { +function getDefaultLastVersionName(versionNames: string[]) { if (versionNames.length === 1) { return versionNames[0]; } else { @@ -229,6 +242,34 @@ function getLastVersionName(versionNames: string[]) { } } +function checkVersionsOptions( + availableVersionNames: string[], + options: VersionsOptions, +) { + const availableVersionNamesMsg = `Available version names are: ${availableVersionNames.join( + ', ', + )}`; + if ( + options.lastVersion && + !availableVersionNames.includes(options.lastVersion) + ) { + throw new Error( + `Docs option lastVersion=${options.lastVersion} is invalid. ${availableVersionNamesMsg}`, + ); + } + const unknownVersionNames = difference( + Object.keys(options.versions), + availableVersionNames, + ); + if (unknownVersionNames.length > 0) { + throw new Error( + `Docs versions option provided configuration for unknown versions: ${unknownVersionNames.join( + ',', + )}. ${availableVersionNamesMsg}`, + ); + } +} + export function readVersionsMetadata({ context, options, @@ -242,10 +283,17 @@ export function readVersionsMetadata({ | 'routeBasePath' | 'includeCurrentVersion' | 'disableVersioning' + | 'lastVersion' + | 'versions' >; }): VersionMetadata[] { const versionNames = readVersionNames(context.siteDir, options); - const lastVersionName = getLastVersionName(versionNames); + + checkVersionsOptions(versionNames, options); + + const lastVersionName = + options.lastVersion ?? getDefaultLastVersionName(versionNames); + const versionsMetadata = versionNames.map((versionName) => createVersionMetadata({ versionName, diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx index 35c497d21b..3cf5316c5e 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/index.tsx @@ -17,6 +17,16 @@ import TOC from '@theme/TOC'; import clsx from 'clsx'; import styles from './styles.module.css'; +import {useActivePlugin, useActiveVersion} from '@theme/hooks/useDocs'; + +// TODO can't we receive the version as props instead? +const useDocVersion = () => { + const version = useActiveVersion(useActivePlugin().pluginId); + if (!version) { + throw new Error("unexpected, can't get version data of doc"); // should not happen + } + return version; +}; function DocItem(props: Props): JSX.Element { const {siteConfig = {}} = useDocusaurusContext(); @@ -30,7 +40,6 @@ function DocItem(props: Props): JSX.Element { editUrl, lastUpdatedAt, lastUpdatedBy, - version, } = metadata; const { frontMatter: { @@ -40,6 +49,7 @@ function DocItem(props: Props): JSX.Element { hide_table_of_contents: hideTableOfContents, }, } = DocContent; + const version = useDocVersion(); const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle; const metaImageUrl = useBaseUrl(metaImage, {absolute: true}); @@ -76,7 +86,7 @@ function DocItem(props: Props): JSX.Element { {version && (
- Version: {version} + Version: {version.label}
)} diff --git a/packages/docusaurus-theme-classic/src/theme/DocVersionSuggestions/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocVersionSuggestions/index.tsx index f047b60b25..05bf3e8426 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocVersionSuggestions/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocVersionSuggestions/index.tsx @@ -43,8 +43,6 @@ function DocVersionSuggestions(): JSX.Element { return <>; } - const activeVersionName = activeVersion.name; - // try to link to same doc in latest version (not always possible) // fallback to main doc of latest version const suggestedDoc = @@ -54,15 +52,15 @@ function DocVersionSuggestions(): JSX.Element {
{ // TODO need refactoring - activeVersionName === 'current' ? ( + activeVersion.name === 'current' ? (
This is unreleased documentation for {siteTitle}{' '} - {activeVersionName} version. + {activeVersion.label} version.
) : (
This is documentation for {siteTitle}{' '} - v{activeVersionName}, which is no longer actively + {activeVersion.label}, which is no longer actively maintained.
) @@ -72,7 +70,7 @@ function DocVersionSuggestions(): JSX.Element { latest version {' '} - ({latestVersionSuggestion.name}). + ({latestVersionSuggestion.label}).
); diff --git a/website/docs/using-plugins.md b/website/docs/using-plugins.md index 0cdc6ec1e4..1249c8d47b 100644 --- a/website/docs/using-plugins.md +++ b/website/docs/using-plugins.md @@ -335,6 +335,33 @@ module.exports = { * in `/docs/next` directory, only versioned docs. */ excludeNextVersionDocs: false, + /** + * The last version is the one we navigate to in priority on versioned sites + * It is the one displayed by default in docs navbar items + * By default, the last version is the first one to appear in versions.json + * By default, the last version is at the "root" (docs have path=/docs/myDoc) + * Note: it is possible to configure the path and label of the last version + * Tip: using lastVersion: 'current' make sense in many cases + */ + lastVersion: undefined, + /** + * The docusaurus versioning defaults don't make sense for all projects + * This gives the ability customize the label and path of each version + * You may not like that default versin + */ + versions: { + /* + Example configuration: + current: { + label: 'Android SDK v2.0.0 (WIP)', + path: 'android-2.0.0', + }, + '1.0.0': { + label: 'Android SDK v1.0.0', + path: 'android-1.0.0', + }, + */ + }, }, ], ], diff --git a/website/docs/versioning.md b/website/docs/versioning.md index c83bd82e53..d0b21bf151 100644 --- a/website/docs/versioning.md +++ b/website/docs/versioning.md @@ -64,9 +64,9 @@ When tagging a new version, the document versioning mechanism will: - Create a versioned sidebars file based from your current [sidebar](docs.md#sidebar) configuration (if it exists) - saved as `versioned_sidebars/version--sidebars.json`. - Append the new version number to `versions.json`. -## Files +## Docs -### Creating new files +### Creating new docs 1. Place the new file into the corresponding version folder. 1. Include the reference for the new file into the corresponding sidebar file, according to version number. @@ -91,7 +91,7 @@ versioned_docs/version-1.0.0/new.md versioned_sidebars/version-1.0.0-sidebars.json ``` -### Linking files +### Linking docs - Remember to include the `.md` extension. - Files will be linked to correct corresponding version. @@ -138,6 +138,35 @@ Example: ## Recommended practices +### Figure out the behavior for the "current" version + +The "current" version is the version name for the `./docs` folder. + +There are different ways to manage versioning, but two very common patterns are: + +- You release v1, and start immediately working on v2 (including its docs) +- You release v1, and will maintain it for some time before thinking about v2. + +Docusaurus defaults work great for the first usecase. + +**For the 2nd usecase**: if you release v1 and don't plan to work on v2 anytime soon, instead of versioning v1 and having to maintain the docs in 2 folders (`./docs` + `./versioned_docs/version-1.0.0`), you may consider using the following configuration instead: + +```json +{ + "lastVersion": "current", + "versions": { + "current": { + "label": "1.0.0", + "path": "1.0.0" + } + } +} +``` + +The docs in `./docs` will be served at `/docs/1.0.0` instead of `/docs/next`, and `1.0.0` will become the default version we link to in the navbar dropdown, and you will only need to maintain a single `./docs` folder. + +See [docs plugin configuration](using-plugins#docusaurusplugin-content-docs) for more details. + ### Version your documentation only when needed For example, you are building a documentation for your npm package `foo` and you are currently in version 1.0.0. You then release a patch version for a minor bug fix and it's now 1.0.1. @@ -156,3 +185,23 @@ Don't use relative paths import within the docs. Because when we cut a version t - import Foo from '../src/components/Foo'; + import Foo from '@site/src/components/Foo'; ``` + +### Global or versioned colocated assets + +You should decide if assets like images and files are per version or shared between versions + +If your assets should be versioned, put them in the docs version, and use relative paths: + +```md +![img alt](./myImage.png) + +[dowload this file](./file.pdf) +``` + +If your assets are global, put them in `/static` and use absolute paths: + +```md +![img alt](/myImage.png) + +[dowload this file](/file.pdf) +``` diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index f89f43975b..3f81e10e24 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -14,13 +14,15 @@ const allDocHomesPaths = [ ...versions.slice(1).map((version) => `/docs/${version}/`), ]; +const isDev = process.env.NODE_ENV === 'development'; + +const isDeployPreview = + process.env.NETLIFY && process.env.CONTEXT === 'deploy-preview'; + const baseUrl = process.env.BASE_URL || '/'; const isBootstrapPreset = process.env.DOCUSAURUS_PRESET === 'bootstrap'; -const isVersioningDisabled = !!process.env.DISABLE_VERSIONING; -if (isBootstrapPreset) { - console.log('Will use bootstrap preset!'); -} +const isVersioningDisabled = !!process.env.DISABLE_VERSIONING; module.exports = { title: 'Docusaurus', @@ -175,6 +177,16 @@ module.exports = { showLastUpdateTime: true, remarkPlugins: [require('./src/plugins/remark-npm2yarn')], disableVersioning: isVersioningDisabled, + lastVersion: isDev || isDeployPreview ? 'current' : undefined, + versions: { + current: { + // path: isDev || isDeployPreview ? '' : 'next', + label: + isDev || isDeployPreview + ? `Next (${isDeployPreview ? 'deploy preview' : 'dev'})` + : 'Next', + }, + }, }, blog: { // routeBasePath: '/', diff --git a/website/src/pages/versions.js b/website/src/pages/versions.js index 61b08bd1d1..fae9580d4e 100644 --- a/website/src/pages/versions.js +++ b/website/src/pages/versions.js @@ -6,20 +6,21 @@ */ import React from 'react'; - -import Layout from '@theme/Layout'; - import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import Link from '@docusaurus/Link'; -import useBaseUrl from '@docusaurus/useBaseUrl'; +import Layout from '@theme/Layout'; -import versions from '../../versions.json'; +import {useVersions, useLatestVersion} from '@theme/hooks/useDocs'; function Version() { - const context = useDocusaurusContext(); - const {siteConfig = {}} = context; - const latestVersion = versions[0]; - const pastVersions = versions.filter((version) => version !== latestVersion); + const {siteConfig} = useDocusaurusContext(); + const versions = useVersions(); + const latestVersion = useLatestVersion(); + const currentVersion = versions.find((version) => version.name === 'current'); + const pastVersions = versions.filter( + (version) => version !== latestVersion && version.name !== 'current', + ); + const repoUrl = `https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`; return ( - {latestVersion} + {latestVersion.label} - Documentation + Documentation - + Release Notes @@ -47,23 +48,25 @@ function Version() { -
-

Next version (Unreleased)

-

Here you can find the documentation for unreleased version.

- - - - - - - - -
master - Documentation - - Source Code -
-
+ {currentVersion !== latestVersion && ( +
+

Next version (Unreleased)

+

Here you can find the documentation for unreleased version.

+ + + + + + + + +
master + Documentation + + Source Code +
+
+ )} {pastVersions.length > 0 && (

Past Versions

@@ -74,15 +77,13 @@ function Version() { {pastVersions.map((version) => ( - - + +
{version}
{version.label} - - Documentation - + Documentation - + Release Notes