mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-15 17:22:35 +02:00
fix(v2): fix docs homepage permalink issues (#2905)
* better fixes for docs homepage * fix tests * create special route for docs homepage + cleanup existing code * no need to create multiple docs parent paths * useful comment * add test for slug + doc home usage at the same time error * remove confusing variable name * fix tests by using same suffix as before for docs base metadata path * metadata: use homePageId correctly for nested docs: the full docId (including /) should be used to compare against homePageId * add folder/testNested test doc * refactor a bit processMetadata, the home should be handled correctly for all versions * Workaround to fix issue when parent layout route (DocPage) has same path as the child route (DocItem): see https://github.com/facebook/docusaurus/issues/2917 * revert homePageId * remove test doc * remove test doc * add useful comment
This commit is contained in:
parent
a3f54d747d
commit
f6b1c85b01
10 changed files with 264 additions and 218 deletions
|
@ -85,7 +85,9 @@ export default function pluginContentDocs(
|
|||
context: LoadContext,
|
||||
opts: Partial<PluginOptions>,
|
||||
): Plugin<LoadedContent | null> {
|
||||
const options = {...DEFAULT_OPTIONS, ...opts};
|
||||
const options: PluginOptions = {...DEFAULT_OPTIONS, ...opts};
|
||||
const homePageDocsRoutePath =
|
||||
options.routeBasePath === '' ? '/' : options.routeBasePath;
|
||||
|
||||
if (options.admonitions) {
|
||||
options.remarkPlugins = options.remarkPlugins.concat([
|
||||
|
@ -112,24 +114,6 @@ export default function pluginContentDocs(
|
|||
} = versioning;
|
||||
const versionsNames = versions.map((version) => `version-${version}`);
|
||||
|
||||
// Docs home page.
|
||||
const homePageDocsRoutePath =
|
||||
options.routeBasePath === '' ? '/' : options.routeBasePath;
|
||||
const isDocsHomePagePath = (permalink: string) => {
|
||||
const documentIdMatch = new RegExp(
|
||||
`^\/(?:${homePageDocsRoutePath}\/)?(?:(?:${versions.join(
|
||||
'|',
|
||||
)}|next)\/)?(.*)`,
|
||||
'i',
|
||||
).exec(permalink);
|
||||
|
||||
if (documentIdMatch) {
|
||||
return documentIdMatch[1] === options.homePageId;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'docusaurus-plugin-content-docs',
|
||||
|
||||
|
@ -307,9 +291,7 @@ Available document ids=
|
|||
return {
|
||||
type: 'link',
|
||||
label: sidebar_label || title,
|
||||
href: isDocsHomePagePath(permalink)
|
||||
? permalink.replace(`/${options.homePageId}`, '')
|
||||
: permalink,
|
||||
href: permalink,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -376,50 +358,8 @@ Available document ids=
|
|||
const genRoutes = async (
|
||||
metadataItems: Metadata[],
|
||||
): Promise<RouteConfig[]> => {
|
||||
const versionsRegex = new RegExp(versionsNames.join('|'), 'i');
|
||||
|
||||
const routes = await Promise.all(
|
||||
metadataItems.map(async (metadataItem) => {
|
||||
const isDocsHomePage =
|
||||
metadataItem.id.replace(versionsRegex, '').replace(/^\//, '') ===
|
||||
options.homePageId;
|
||||
if (isDocsHomePage) {
|
||||
const versionDocsPathPrefix =
|
||||
(metadataItem?.version === versioning.latestVersion
|
||||
? ''
|
||||
: metadataItem.version!) ?? '';
|
||||
|
||||
const docsBaseMetadata = createDocsBaseMetadata(
|
||||
metadataItem.version!,
|
||||
);
|
||||
docsBaseMetadata.isHomePage = true;
|
||||
docsBaseMetadata.homePagePath = normalizeUrl([
|
||||
baseUrl,
|
||||
homePageDocsRoutePath,
|
||||
versionDocsPathPrefix,
|
||||
]);
|
||||
|
||||
const docsBaseMetadataPath = await createData(
|
||||
`${docuHash(metadataItem.source)}-base.json`,
|
||||
JSON.stringify(docsBaseMetadata, null, 2),
|
||||
);
|
||||
|
||||
// Add a route for docs home page.
|
||||
addRoute({
|
||||
path: normalizeUrl([
|
||||
baseUrl,
|
||||
homePageDocsRoutePath,
|
||||
versionDocsPathPrefix,
|
||||
]),
|
||||
component: docLayoutComponent,
|
||||
exact: true,
|
||||
modules: {
|
||||
docsMetadata: aliasedSource(docsBaseMetadataPath),
|
||||
content: metadataItem.source,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
await createData(
|
||||
// Note that this created data path must be in sync with
|
||||
// metadataPath provided to mdx-loader.
|
||||
|
@ -438,15 +378,14 @@ Available document ids=
|
|||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
routes
|
||||
// Do not create a route for a document serve as docs home page.
|
||||
// TODO: need way to do this filtering when generating routes for better perf.
|
||||
.filter(({path}) => !isDocsHomePagePath(path))
|
||||
.sort((a, b) => (a.path > b.path ? 1 : b.path > a.path ? -1 : 0))
|
||||
return routes.sort((a, b) =>
|
||||
a.path > b.path ? 1 : b.path > a.path ? -1 : 0,
|
||||
);
|
||||
};
|
||||
|
||||
// This is the base route of the document root (for a doc given version)
|
||||
// (/docs, /docs/next, /docs/1.0 etc...)
|
||||
// The component applies the layout and renders the appropriate doc
|
||||
const addBaseRoute = async (
|
||||
docsBaseRoute: string,
|
||||
docsBaseMetadata: DocsBaseMetadata,
|
||||
|
@ -454,14 +393,20 @@ Available document ids=
|
|||
priority?: number,
|
||||
) => {
|
||||
const docsBaseMetadataPath = await createData(
|
||||
`${docuHash(docsBaseRoute)}.json`,
|
||||
`${docuHash(normalizeUrl([docsBaseRoute, ':route']))}.json`,
|
||||
JSON.stringify(docsBaseMetadata, null, 2),
|
||||
);
|
||||
|
||||
// Important: the layout component should not end with /,
|
||||
// as it conflicts with the home doc
|
||||
// Workaround fix for https://github.com/facebook/docusaurus/issues/2917
|
||||
const path = docsBaseRoute === '/' ? '' : docsBaseRoute;
|
||||
|
||||
addRoute({
|
||||
path: docsBaseRoute,
|
||||
component: docLayoutComponent,
|
||||
routes,
|
||||
path,
|
||||
exact: false, // allow matching /docs/* as well
|
||||
component: docLayoutComponent, // main docs component (DocPage)
|
||||
routes, // subroute for each doc
|
||||
modules: {
|
||||
docsMetadata: aliasedSource(docsBaseMetadataPath),
|
||||
},
|
||||
|
@ -499,21 +444,20 @@ Available document ids=
|
|||
);
|
||||
|
||||
const isLatestVersion = version === versioning.latestVersion;
|
||||
const docsBasePermalink = normalizeUrl([
|
||||
const docsBaseRoute = normalizeUrl([
|
||||
baseUrl,
|
||||
routeBasePath,
|
||||
isLatestVersion ? '' : version,
|
||||
]);
|
||||
const docsBaseRoute = normalizeUrl([docsBasePermalink, ':route']);
|
||||
const docsBaseMetadata = createDocsBaseMetadata(version);
|
||||
|
||||
// We want latest version route config to be placed last in the
|
||||
// generated routeconfig. Otherwise, `/docs/next/foo` will match
|
||||
// `/docs/:route` instead of `/docs/next/:route`.
|
||||
return addBaseRoute(
|
||||
docsBaseRoute,
|
||||
docsBaseMetadata,
|
||||
routes,
|
||||
// We want latest version route config to be placed last in the
|
||||
// generated routeconfig. Otherwise, `/docs/next/foo` will match
|
||||
// `/docs/:route` instead of `/docs/next/:route`.
|
||||
isLatestVersion ? -1 : undefined,
|
||||
);
|
||||
}),
|
||||
|
@ -521,8 +465,7 @@ Available document ids=
|
|||
} else {
|
||||
const routes = await genRoutes(Object.values(content.docsMetadata));
|
||||
const docsBaseMetadata = createDocsBaseMetadata();
|
||||
|
||||
const docsBaseRoute = normalizeUrl([baseUrl, routeBasePath, ':route']);
|
||||
const docsBaseRoute = normalizeUrl([baseUrl, routeBasePath]);
|
||||
return addBaseRoute(docsBaseRoute, docsBaseMetadata, routes);
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue