mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-12 08:37:25 +02:00
fix(v2): alpha 62 doc fixes (#3381)
* deprecated nextVersionLabel option * useActivePlugin failfast option * remove deprecated option nextVersionLabel * routeBasePath: '' should be forbidden * routeBasePath: '' should be forbidden * Docs: do not show version badge if there is only 1 version: https://github.com/facebook/docusaurus/issues/3362 * allow sidebars file to not exist: fallback to empty sidebars https://githu.com/facebook/docusaurus/issues/3366
This commit is contained in:
parent
2a3fe86579
commit
a4769e3f30
11 changed files with 80 additions and 35 deletions
|
@ -115,9 +115,13 @@ describe('loadSidebars', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('unexisting path', () => {
|
test('unexisting path', () => {
|
||||||
|
/*
|
||||||
expect(() => loadSidebars('badpath')).toThrowErrorMatchingInlineSnapshot(
|
expect(() => loadSidebars('badpath')).toThrowErrorMatchingInlineSnapshot(
|
||||||
`"No sidebar file exist at path: badpath"`,
|
`"No sidebar file exist at path: badpath"`,
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
|
// See https://github.com/facebook/docusaurus/issues/3366
|
||||||
|
expect(loadSidebars('badpath')).toEqual({});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('undefined path', () => {
|
test('undefined path', () => {
|
||||||
|
|
|
@ -32,6 +32,17 @@ describe('docsClientUtils', () => {
|
||||||
expect(getActivePlugin(data, '/')).toEqual(undefined);
|
expect(getActivePlugin(data, '/')).toEqual(undefined);
|
||||||
expect(getActivePlugin(data, '/xyz')).toEqual(undefined);
|
expect(getActivePlugin(data, '/xyz')).toEqual(undefined);
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
getActivePlugin(data, '/', {failfast: true}),
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
`"Can't find active docs plugin for pathname=/, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
|
||||||
|
);
|
||||||
|
expect(() =>
|
||||||
|
getActivePlugin(data, '/xyz', {failfast: true}),
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(
|
||||||
|
`"Can't find active docs plugin for pathname=/xyz, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
|
||||||
|
);
|
||||||
|
|
||||||
const activePluginIos: ActivePlugin = {
|
const activePluginIos: ActivePlugin = {
|
||||||
pluginId: 'pluginIosId',
|
pluginId: 'pluginIosId',
|
||||||
pluginData: data.pluginIosId,
|
pluginData: data.pluginIosId,
|
||||||
|
@ -115,6 +126,9 @@ describe('docsClientUtils', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
expect(getActiveVersion(data, '/someUnknownPath')).toEqual(undefined);
|
||||||
|
|
||||||
expect(getActiveVersion(data, '/docs/next')?.name).toEqual('next');
|
expect(getActiveVersion(data, '/docs/next')?.name).toEqual('next');
|
||||||
expect(getActiveVersion(data, '/docs/next/')?.name).toEqual('next');
|
expect(getActiveVersion(data, '/docs/next/')?.name).toEqual('next');
|
||||||
expect(getActiveVersion(data, '/docs/next/someDoc')?.name).toEqual('next');
|
expect(getActiveVersion(data, '/docs/next/someDoc')?.name).toEqual('next');
|
||||||
|
|
|
@ -20,13 +20,27 @@ export type ActivePlugin = {
|
||||||
pluginData: GlobalPluginData;
|
pluginData: GlobalPluginData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type GetActivePluginOptions = {failfast?: boolean};
|
||||||
|
|
||||||
// get the data of the plugin that is currently "active"
|
// get the data of the plugin that is currently "active"
|
||||||
// ie the docs of that plugin are currently browsed
|
// ie the docs of that plugin are currently browsed
|
||||||
// it is useful to support multiple docs plugin instances
|
// it is useful to support multiple docs plugin instances
|
||||||
export const getActivePlugin = (
|
export function getActivePlugin(
|
||||||
allPluginDatas: Record<string, GlobalPluginData>,
|
allPluginDatas: Record<string, GlobalPluginData>,
|
||||||
pathname: string,
|
pathname: string,
|
||||||
): ActivePlugin | undefined => {
|
options: {failfast: true}, // use fail-fast option if you know for sure one plugin instance is active
|
||||||
|
): ActivePlugin;
|
||||||
|
export function getActivePlugin(
|
||||||
|
allPluginDatas: Record<string, GlobalPluginData>,
|
||||||
|
pathname: string,
|
||||||
|
options?: GetActivePluginOptions,
|
||||||
|
): ActivePlugin | undefined;
|
||||||
|
|
||||||
|
export function getActivePlugin(
|
||||||
|
allPluginDatas: Record<string, GlobalPluginData>,
|
||||||
|
pathname: string,
|
||||||
|
options: GetActivePluginOptions = {},
|
||||||
|
): ActivePlugin | undefined {
|
||||||
const activeEntry = Object.entries(allPluginDatas).find(
|
const activeEntry = Object.entries(allPluginDatas).find(
|
||||||
([_id, pluginData]) => {
|
([_id, pluginData]) => {
|
||||||
return !!matchPath(pathname, {
|
return !!matchPath(pathname, {
|
||||||
|
@ -37,10 +51,22 @@ export const getActivePlugin = (
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return activeEntry
|
const activePlugin: ActivePlugin | undefined = activeEntry
|
||||||
? {pluginId: activeEntry[0], pluginData: activeEntry[1]}
|
? {pluginId: activeEntry[0], pluginData: activeEntry[1]}
|
||||||
: undefined;
|
: undefined;
|
||||||
};
|
|
||||||
|
if (!activePlugin && options.failfast) {
|
||||||
|
throw new Error(
|
||||||
|
`Can't find active docs plugin for pathname=${pathname}, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
|
||||||
|
allPluginDatas,
|
||||||
|
)
|
||||||
|
.map((plugin) => plugin.path)
|
||||||
|
.join(', ')}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return activePlugin;
|
||||||
|
}
|
||||||
|
|
||||||
export type ActiveDocContext = {
|
export type ActiveDocContext = {
|
||||||
activeVersion?: Version;
|
activeVersion?: Version;
|
||||||
|
|
|
@ -200,9 +200,14 @@ export function loadSidebars(sidebarFilePath: string): Sidebars {
|
||||||
if (!sidebarFilePath) {
|
if (!sidebarFilePath) {
|
||||||
throw new Error(`sidebarFilePath not provided: ${sidebarFilePath}`);
|
throw new Error(`sidebarFilePath not provided: ${sidebarFilePath}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sidebars file is optional, some users use docs without sidebars!
|
||||||
|
// See https://github.com/facebook/docusaurus/issues/3366
|
||||||
if (!fs.existsSync(sidebarFilePath)) {
|
if (!fs.existsSync(sidebarFilePath)) {
|
||||||
throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`);
|
// throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want sidebars to be cached because of hot reloading.
|
// We don't want sidebars to be cached because of hot reloading.
|
||||||
const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON;
|
const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON;
|
||||||
return normalizeSidebars(sidebarJson);
|
return normalizeSidebars(sidebarJson);
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
getActiveVersion,
|
getActiveVersion,
|
||||||
getActiveDocContext,
|
getActiveDocContext,
|
||||||
getDocVersionSuggestions,
|
getDocVersionSuggestions,
|
||||||
|
GetActivePluginOptions,
|
||||||
} from '../../client/docsClientUtils';
|
} from '../../client/docsClientUtils';
|
||||||
|
|
||||||
const useAllDocsData = (): Record<string, GlobalPluginData> =>
|
const useAllDocsData = (): Record<string, GlobalPluginData> =>
|
||||||
|
@ -26,10 +27,10 @@ const useAllDocsData = (): Record<string, GlobalPluginData> =>
|
||||||
const useDocsData = (pluginId: string | undefined) =>
|
const useDocsData = (pluginId: string | undefined) =>
|
||||||
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
|
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;
|
||||||
|
|
||||||
export const useActivePlugin = () => {
|
export const useActivePlugin = (options: GetActivePluginOptions = {}) => {
|
||||||
const data = useAllDocsData();
|
const data = useAllDocsData();
|
||||||
const {pathname} = useLocation();
|
const {pathname} = useLocation();
|
||||||
return getActivePlugin(data, pathname);
|
return getActivePlugin(data, pathname, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
// versions are returned ordered (most recent first)
|
// versions are returned ordered (most recent first)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
|
||||||
import {LoadContext} from '@docusaurus/types';
|
import {LoadContext} from '@docusaurus/types';
|
||||||
import {normalizeUrl} from '@docusaurus/utils';
|
import {normalizeUrl} from '@docusaurus/utils';
|
||||||
import {difference} from 'lodash';
|
import {difference} from 'lodash';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
// retro-compatibility: no prefix for the default plugin id
|
// retro-compatibility: no prefix for the default plugin id
|
||||||
function addPluginIdPrefix(fileOrDir: string, pluginId: string): string {
|
function addPluginIdPrefix(fileOrDir: string, pluginId: string): string {
|
||||||
|
@ -222,9 +223,13 @@ function checkVersionMetadataPaths({
|
||||||
`The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`,
|
`The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://github.com/facebook/docusaurus/issues/3366
|
||||||
if (!fs.existsSync(sidebarFilePath)) {
|
if (!fs.existsSync(sidebarFilePath)) {
|
||||||
throw new Error(
|
console.log(
|
||||||
`The sidebar file does not exist for version [${versionName}]. A sidebar file is expected to be found at ${sidebarFilePath}`,
|
chalk.yellow(
|
||||||
|
`The sidebar file of docs version [${versionName}] does not exist. It is optional, but should rather be provided at ${sidebarFilePath}`,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,6 @@ describe('themeConfig', () => {
|
||||||
{
|
{
|
||||||
type: 'docsVersionDropdown',
|
type: 'docsVersionDropdown',
|
||||||
position: 'left',
|
position: 'left',
|
||||||
nextVersionLabel: '2.0.0-next',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: 'docs/next/support',
|
to: 'docs/next/support',
|
||||||
|
|
|
@ -17,16 +17,11 @@ import TOC from '@theme/TOC';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import {useActivePlugin, useActiveVersion} from '@theme/hooks/useDocs';
|
import {
|
||||||
|
useActivePlugin,
|
||||||
// TODO can't we receive the version as props instead?
|
useVersions,
|
||||||
const useDocVersion = () => {
|
useActiveVersion,
|
||||||
const version = useActiveVersion(useActivePlugin().pluginId);
|
} from '@theme/hooks/useDocs';
|
||||||
if (!version) {
|
|
||||||
throw new Error("unexpected, can't get version data of doc"); // should not happen
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
};
|
|
||||||
|
|
||||||
function DocItem(props: Props): JSX.Element {
|
function DocItem(props: Props): JSX.Element {
|
||||||
const {siteConfig = {}} = useDocusaurusContext();
|
const {siteConfig = {}} = useDocusaurusContext();
|
||||||
|
@ -49,7 +44,15 @@ function DocItem(props: Props): JSX.Element {
|
||||||
hide_table_of_contents: hideTableOfContents,
|
hide_table_of_contents: hideTableOfContents,
|
||||||
},
|
},
|
||||||
} = DocContent;
|
} = DocContent;
|
||||||
const version = useDocVersion();
|
|
||||||
|
const {pluginId} = useActivePlugin({failfast: true});
|
||||||
|
const versions = useVersions(pluginId);
|
||||||
|
const version = useActiveVersion(pluginId);
|
||||||
|
|
||||||
|
// If site is not versioned or only one version is included
|
||||||
|
// we don't show the version badge
|
||||||
|
// See https://github.com/facebook/docusaurus/issues/3362
|
||||||
|
const showVersionBadge = versions.length > 1;
|
||||||
|
|
||||||
const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle;
|
const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle;
|
||||||
const metaImageUrl = useBaseUrl(metaImage, {absolute: true});
|
const metaImageUrl = useBaseUrl(metaImage, {absolute: true});
|
||||||
|
@ -83,7 +86,7 @@ function DocItem(props: Props): JSX.Element {
|
||||||
<DocVersionSuggestions />
|
<DocVersionSuggestions />
|
||||||
<div className={styles.docItemContainer}>
|
<div className={styles.docItemContainer}>
|
||||||
<article>
|
<article>
|
||||||
{version && (
|
{showVersionBadge && (
|
||||||
<div>
|
<div>
|
||||||
<span className="badge badge--secondary">
|
<span className="badge badge--secondary">
|
||||||
Version: {version.label}
|
Version: {version.label}
|
||||||
|
|
|
@ -14,16 +14,6 @@ import {
|
||||||
useDocVersionSuggestions,
|
useDocVersionSuggestions,
|
||||||
} from '@theme/hooks/useDocs';
|
} from '@theme/hooks/useDocs';
|
||||||
|
|
||||||
const useMandatoryActiveDocsPluginId = () => {
|
|
||||||
const activePlugin = useActivePlugin();
|
|
||||||
if (!activePlugin) {
|
|
||||||
throw new Error(
|
|
||||||
'DocVersionCallout is only supposed to be used on docs-related routes',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return activePlugin.pluginId;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getVersionMainDoc = (version) =>
|
const getVersionMainDoc = (version) =>
|
||||||
version.docs.find((doc) => doc.id === version.mainDocId);
|
version.docs.find((doc) => doc.id === version.mainDocId);
|
||||||
|
|
||||||
|
@ -31,7 +21,7 @@ function DocVersionSuggestions(): JSX.Element {
|
||||||
const {
|
const {
|
||||||
siteConfig: {title: siteTitle},
|
siteConfig: {title: siteTitle},
|
||||||
} = useDocusaurusContext();
|
} = useDocusaurusContext();
|
||||||
const pluginId = useMandatoryActiveDocsPluginId();
|
const {pluginId} = useActivePlugin({failfast: true});
|
||||||
const activeVersion = useActiveVersion(pluginId);
|
const activeVersion = useActiveVersion(pluginId);
|
||||||
const {
|
const {
|
||||||
latestDocSuggestion,
|
latestDocSuggestion,
|
||||||
|
|
|
@ -56,7 +56,6 @@ const DocsVersionDropdownNavbarItemSchema = Joi.object({
|
||||||
type: Joi.string().equal('docsVersionDropdown').required(),
|
type: Joi.string().equal('docsVersionDropdown').required(),
|
||||||
position: NavbarItemPosition,
|
position: NavbarItemPosition,
|
||||||
docsPluginId: Joi.string(),
|
docsPluginId: Joi.string(),
|
||||||
nextVersionLabel: Joi.string().default('Next'), // TODO remove soon
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Can this be made easier? :/
|
// Can this be made easier? :/
|
||||||
|
|
|
@ -250,7 +250,6 @@ module.exports = {
|
||||||
{
|
{
|
||||||
type: 'docsVersionDropdown',
|
type: 'docsVersionDropdown',
|
||||||
position: 'left',
|
position: 'left',
|
||||||
nextVersionLabel: '2.0.0-next',
|
|
||||||
},
|
},
|
||||||
{to: 'blog', label: 'Blog', position: 'left'},
|
{to: 'blog', label: 'Blog', position: 'left'},
|
||||||
{to: 'showcase', label: 'Showcase', position: 'left'},
|
{to: 'showcase', label: 'Showcase', position: 'left'},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue