fix(v2): deprecate docs homePageId in favor of frontmatter "slug: /" (#3228)

* homePageId => deprecated

* docs prettier
This commit is contained in:
Sébastien Lorber 2020-08-06 18:31:50 +02:00 committed by GitHub
parent 0079f0e8d1
commit 0a33a52301
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 109 additions and 79 deletions

View file

@ -192,6 +192,7 @@ Object {
\\"title\\": \\"Bar\\",
\\"description\\": \\"This is custom description\\",
\\"source\\": \\"@site/docs/foo/bar.md\\",
\\"slug\\": \\"/foo/bar\\",
\\"permalink\\": \\"/docs/foo/bar\\",
\\"sidebar\\": \\"docs\\",
\\"next\\": {
@ -206,6 +207,7 @@ Object {
\\"title\\": \\"baz\\",
\\"description\\": \\"Images\\",
\\"source\\": \\"@site/docs/foo/baz.md\\",
\\"slug\\": \\"/foo/bazSlug.html\\",
\\"permalink\\": \\"/docs/foo/bazSlug.html\\",
\\"sidebar\\": \\"docs\\",
\\"previous\\": {
@ -224,6 +226,7 @@ Object {
\\"title\\": \\"Hello, World !\\",
\\"description\\": \\"Hi, Endilie here :)\\",
\\"source\\": \\"@site/docs/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/\\",
\\"sidebar\\": \\"docs\\",
\\"previous\\": {
@ -238,6 +241,7 @@ Object {
\\"title\\": \\"ipsum\\",
\\"description\\": \\"Lorem ipsum.\\",
\\"source\\": \\"@site/docs/ipsum.md\\",
\\"slug\\": \\"/ipsum\\",
\\"permalink\\": \\"/docs/ipsum\\",
\\"editUrl\\": null
}",
@ -248,6 +252,7 @@ Object {
\\"title\\": \\"lorem\\",
\\"description\\": \\"Lorem ipsum.\\",
\\"source\\": \\"@site/docs/lorem.md\\",
\\"slug\\": \\"/lorem\\",
\\"permalink\\": \\"/docs/lorem\\",
\\"editUrl\\": \\"https://github.com/customUrl/docs/lorem.md\\"
}",
@ -258,6 +263,7 @@ Object {
\\"title\\": \\"rootAbsoluteSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/rootAbsoluteSlug.md\\",
\\"slug\\": \\"/rootAbsoluteSlug\\",
\\"permalink\\": \\"/docs/rootAbsoluteSlug\\"
}",
"site-docs-root-relative-slug-md-3dd.json": "{
@ -267,6 +273,7 @@ Object {
\\"title\\": \\"rootRelativeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/rootRelativeSlug.md\\",
\\"slug\\": \\"/rootRelativeSlug\\",
\\"permalink\\": \\"/docs/rootRelativeSlug\\"
}",
"site-docs-root-resolved-slug-md-4d1.json": "{
@ -276,6 +283,7 @@ Object {
\\"title\\": \\"rootResolvedSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/rootResolvedSlug.md\\",
\\"slug\\": \\"/hey/rootResolvedSlug\\",
\\"permalink\\": \\"/docs/hey/rootResolvedSlug\\"
}",
"site-docs-root-try-to-escape-slug-md-9ee.json": "{
@ -285,6 +293,7 @@ Object {
\\"title\\": \\"rootTryToEscapeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/rootTryToEscapeSlug.md\\",
\\"slug\\": \\"/rootTryToEscapeSlug\\",
\\"permalink\\": \\"/docs/rootTryToEscapeSlug\\"
}",
"site-docs-slugs-absolute-slug-md-4e8.json": "{
@ -294,6 +303,7 @@ Object {
\\"title\\": \\"absoluteSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/absoluteSlug.md\\",
\\"slug\\": \\"/absoluteSlug\\",
\\"permalink\\": \\"/docs/absoluteSlug\\"
}",
"site-docs-slugs-relative-slug-md-d1c.json": "{
@ -303,6 +313,7 @@ Object {
\\"title\\": \\"relativeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/relativeSlug.md\\",
\\"slug\\": \\"/slugs/relativeSlug\\",
\\"permalink\\": \\"/docs/slugs/relativeSlug\\"
}",
"site-docs-slugs-resolved-slug-md-02b.json": "{
@ -312,6 +323,7 @@ Object {
\\"title\\": \\"resolvedSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/resolvedSlug.md\\",
\\"slug\\": \\"/slugs/hey/resolvedSlug\\",
\\"permalink\\": \\"/docs/slugs/hey/resolvedSlug\\"
}",
"site-docs-slugs-try-to-escape-slug-md-70d.json": "{
@ -321,6 +333,7 @@ Object {
\\"title\\": \\"tryToEscapeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/tryToEscapeSlug.md\\",
\\"slug\\": \\"/tryToEscapeSlug\\",
\\"permalink\\": \\"/docs/tryToEscapeSlug\\"
}",
}
@ -630,6 +643,7 @@ Object {
\\"title\\": \\"team\\",
\\"description\\": \\"Team current version\\",
\\"source\\": \\"@site/community/team.md\\",
\\"slug\\": \\"/team\\",
\\"permalink\\": \\"/community/next/team\\",
\\"version\\": \\"next\\",
\\"sidebar\\": \\"community\\"
@ -641,6 +655,7 @@ Object {
\\"title\\": \\"team\\",
\\"description\\": \\"Team 1.0.0\\",
\\"source\\": \\"@site/community_versioned_docs/version-1.0.0/team.md\\",
\\"slug\\": \\"/team\\",
\\"permalink\\": \\"/community/team\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/community\\"
@ -1070,6 +1085,7 @@ Object {
\\"title\\": \\"bar\\",
\\"description\\": \\"This is next version of bar.\\",
\\"source\\": \\"@site/docs/foo/bar.md\\",
\\"slug\\": \\"/foo/barSlug\\",
\\"permalink\\": \\"/docs/next/foo/barSlug\\",
\\"version\\": \\"next\\",
\\"sidebar\\": \\"docs\\",
@ -1085,6 +1101,7 @@ Object {
\\"title\\": \\"hello\\",
\\"description\\": \\"Hello next !\\",
\\"source\\": \\"@site/docs/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/next/\\",
\\"version\\": \\"next\\",
\\"sidebar\\": \\"docs\\",
@ -1100,6 +1117,7 @@ Object {
\\"title\\": \\"absoluteSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/absoluteSlug.md\\",
\\"slug\\": \\"/absoluteSlug\\",
\\"permalink\\": \\"/docs/next/absoluteSlug\\",
\\"version\\": \\"next\\"
}",
@ -1110,6 +1128,7 @@ Object {
\\"title\\": \\"relativeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/relativeSlug.md\\",
\\"slug\\": \\"/slugs/relativeSlug\\",
\\"permalink\\": \\"/docs/next/slugs/relativeSlug\\",
\\"version\\": \\"next\\"
}",
@ -1120,6 +1139,7 @@ Object {
\\"title\\": \\"resolvedSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/resolvedSlug.md\\",
\\"slug\\": \\"/slugs/hey/resolvedSlug\\",
\\"permalink\\": \\"/docs/next/slugs/hey/resolvedSlug\\",
\\"version\\": \\"next\\"
}",
@ -1130,6 +1150,7 @@ Object {
\\"title\\": \\"tryToEscapeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/docs/slugs/tryToEscapeSlug.md\\",
\\"slug\\": \\"/tryToEscapeSlug\\",
\\"permalink\\": \\"/docs/next/tryToEscapeSlug\\",
\\"version\\": \\"next\\"
}",
@ -1140,6 +1161,7 @@ Object {
\\"title\\": \\"bar\\",
\\"description\\": \\"Bar 1.0.0 !\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.0/foo/bar.md\\",
\\"slug\\": \\"/foo/barSlug\\",
\\"permalink\\": \\"/docs/1.0.0/foo/barSlug\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/docs\\",
@ -1155,6 +1177,7 @@ Object {
\\"title\\": \\"baz\\",
\\"description\\": \\"Baz 1.0.0 ! This will be deleted in next subsequent versions.\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.0/foo/baz.md\\",
\\"slug\\": \\"/foo/baz\\",
\\"permalink\\": \\"/docs/1.0.0/foo/baz\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/docs\\",
@ -1174,6 +1197,7 @@ Object {
\\"title\\": \\"hello\\",
\\"description\\": \\"Hello 1.0.0 !\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.0/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/1.0.0/\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/docs\\",
@ -1189,6 +1213,7 @@ Object {
\\"title\\": \\"bar\\",
\\"description\\": \\"Bar 1.0.1 !\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.1/foo/bar.md\\",
\\"slug\\": \\"/foo/bar\\",
\\"permalink\\": \\"/docs/foo/bar\\",
\\"version\\": \\"1.0.1\\",
\\"sidebar\\": \\"version-1.0.1/docs\\",
@ -1204,6 +1229,7 @@ Object {
\\"title\\": \\"hello\\",
\\"description\\": \\"Hello 1.0.1 !\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.1/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/\\",
\\"version\\": \\"1.0.1\\",
\\"sidebar\\": \\"version-1.0.1/docs\\",
@ -1219,6 +1245,7 @@ Object {
\\"title\\": \\"rootAbsoluteSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md\\",
\\"slug\\": \\"/rootAbsoluteSlug\\",
\\"permalink\\": \\"/docs/withSlugs/rootAbsoluteSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1229,6 +1256,7 @@ Object {
\\"title\\": \\"rootRelativeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/rootRelativeSlug.md\\",
\\"slug\\": \\"/rootRelativeSlug\\",
\\"permalink\\": \\"/docs/withSlugs/rootRelativeSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1239,6 +1267,7 @@ Object {
\\"title\\": \\"rootResolvedSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/rootResolvedSlug.md\\",
\\"slug\\": \\"/hey/rootResolvedSlug\\",
\\"permalink\\": \\"/docs/withSlugs/hey/rootResolvedSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1249,6 +1278,7 @@ Object {
\\"title\\": \\"rootTryToEscapeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md\\",
\\"slug\\": \\"/rootTryToEscapeSlug\\",
\\"permalink\\": \\"/docs/withSlugs/rootTryToEscapeSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1259,6 +1289,7 @@ Object {
\\"title\\": \\"absoluteSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md\\",
\\"slug\\": \\"/absoluteSlug\\",
\\"permalink\\": \\"/docs/withSlugs/absoluteSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1269,6 +1300,7 @@ Object {
\\"title\\": \\"relativeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/slugs/relativeSlug.md\\",
\\"slug\\": \\"/slugs/relativeSlug\\",
\\"permalink\\": \\"/docs/withSlugs/slugs/relativeSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1279,6 +1311,7 @@ Object {
\\"title\\": \\"resolvedSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md\\",
\\"slug\\": \\"/slugs/hey/resolvedSlug\\",
\\"permalink\\": \\"/docs/withSlugs/slugs/hey/resolvedSlug\\",
\\"version\\": \\"withSlugs\\"
}",
@ -1289,6 +1322,7 @@ Object {
\\"title\\": \\"tryToEscapeSlug\\",
\\"description\\": \\"Lorem\\",
\\"source\\": \\"@site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md\\",
\\"slug\\": \\"/tryToEscapeSlug\\",
\\"permalink\\": \\"/docs/withSlugs/tryToEscapeSlug\\",
\\"version\\": \\"withSlugs\\"
}",

View file

@ -205,6 +205,7 @@ describe('simple website', () => {
unversionedId: 'hello',
isDocsHomePage: true,
permalink: '/docs/',
slug: '/',
previous: {
title: 'baz',
permalink: '/docs/foo/bazSlug.html',
@ -224,6 +225,7 @@ describe('simple website', () => {
permalink: '/docs/foo/bazSlug.html',
},
permalink: '/docs/foo/bar',
slug: '/foo/bar',
sidebar: 'docs',
source: path.join('@site', pluginPath, 'foo', 'bar.md'),
title: 'Bar',
@ -349,6 +351,7 @@ describe('versioned website', () => {
unversionedId: 'foo/bar',
isDocsHomePage: false,
permalink: '/docs/next/foo/barSlug',
slug: '/foo/barSlug',
source: path.join('@site', routeBasePath, 'foo', 'bar.md'),
title: 'bar',
description: 'This is next version of bar.',
@ -364,6 +367,7 @@ describe('versioned website', () => {
unversionedId: 'hello',
isDocsHomePage: true,
permalink: '/docs/next/',
slug: '/',
source: path.join('@site', routeBasePath, 'hello.md'),
title: 'hello',
description: 'Hello next !',
@ -379,6 +383,7 @@ describe('versioned website', () => {
unversionedId: 'hello',
isDocsHomePage: true,
permalink: '/docs/',
slug: '/',
source: path.join(
'@site',
path.relative(siteDir, versionedDir),
@ -399,6 +404,7 @@ describe('versioned website', () => {
unversionedId: 'foo/baz',
isDocsHomePage: false,
permalink: '/docs/1.0.0/foo/baz',
slug: '/foo/baz',
source: path.join(
'@site',
path.relative(siteDir, versionedDir),
@ -552,6 +558,7 @@ describe('versioned website (community)', () => {
unversionedId: 'team',
isDocsHomePage: false,
permalink: '/community/next/team',
slug: '/team',
source: path.join('@site', routeBasePath, 'team.md'),
title: 'team',
description: 'Team current version',
@ -563,6 +570,7 @@ describe('versioned website (community)', () => {
unversionedId: 'team',
isDocsHomePage: false,
permalink: '/community/team',
slug: '/team',
source: path.join(
'@site',
path.relative(siteDir, versionedDir),

View file

@ -83,6 +83,7 @@ describe('simple site', () => {
unversionedId: 'foo/bar',
isDocsHomePage: false,
permalink: '/docs/foo/bar',
slug: '/foo/bar',
title: 'Bar',
description: 'This is custom description',
});
@ -91,6 +92,7 @@ describe('simple site', () => {
unversionedId: 'hello',
isDocsHomePage: false,
permalink: '/docs/hello',
slug: '/hello',
title: 'Hello, World !',
description: `Hi, Endilie here :)`,
});
@ -112,6 +114,7 @@ describe('simple site', () => {
unversionedId: 'hello',
isDocsHomePage: true,
permalink: '/docs/',
slug: '/',
title: 'Hello, World !',
description: `Hi, Endilie here :)`,
});
@ -133,6 +136,7 @@ describe('simple site', () => {
unversionedId: 'foo/bar',
isDocsHomePage: true,
permalink: '/docs/',
slug: '/',
title: 'Bar',
description: 'This is custom description',
});
@ -154,6 +158,7 @@ describe('simple site', () => {
unversionedId: 'foo/baz',
isDocsHomePage: false,
permalink: '/docs/foo/bazSlug.html',
slug: '/foo/bazSlug.html',
title: 'baz',
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/docs/foo/baz.md',
@ -167,6 +172,7 @@ describe('simple site', () => {
unversionedId: 'lorem',
isDocsHomePage: false,
permalink: '/docs/lorem',
slug: '/lorem',
title: 'lorem',
editUrl: 'https://github.com/customUrl/docs/lorem.md',
description: 'Lorem ipsum.',
@ -190,6 +196,7 @@ describe('simple site', () => {
unversionedId: 'lorem',
isDocsHomePage: false,
permalink: '/docs/lorem',
slug: '/lorem',
title: 'lorem',
editUrl: 'https://github.com/customUrl/docs/lorem.md',
description: 'Lorem ipsum.',
@ -215,6 +222,7 @@ describe('simple site', () => {
unversionedId: 'ipsum',
isDocsHomePage: false,
permalink: '/docs/ipsum',
slug: '/ipsum',
title: 'ipsum',
editUrl: null,
description: 'Lorem ipsum.',
@ -327,6 +335,7 @@ describe('versioned site', () => {
unversionedId: 'foo/bar',
isDocsHomePage: false,
permalink: '/docs/next/foo/barSlug',
slug: '/foo/barSlug',
title: 'bar',
description: 'This is next version of bar.',
version: 'next',
@ -336,6 +345,7 @@ describe('versioned site', () => {
unversionedId: 'hello',
isDocsHomePage: false,
permalink: '/docs/next/hello',
slug: '/hello',
title: 'hello',
description: 'Hello next !',
version: 'next',
@ -348,6 +358,7 @@ describe('versioned site', () => {
unversionedId: 'foo/bar',
isDocsHomePage: false,
permalink: '/docs/1.0.0/foo/barSlug',
slug: '/foo/barSlug',
title: 'bar',
description: 'Bar 1.0.0 !',
version: '1.0.0',
@ -357,6 +368,7 @@ describe('versioned site', () => {
unversionedId: 'hello',
isDocsHomePage: false,
permalink: '/docs/1.0.0/hello',
slug: '/hello',
title: 'hello',
description: 'Hello 1.0.0 !',
version: '1.0.0',
@ -366,6 +378,7 @@ describe('versioned site', () => {
unversionedId: 'foo/bar',
isDocsHomePage: false,
permalink: '/docs/foo/bar',
slug: '/foo/bar',
title: 'bar',
description: 'Bar 1.0.1 !',
version: '1.0.1',
@ -375,6 +388,7 @@ describe('versioned site', () => {
unversionedId: 'hello',
isDocsHomePage: false,
permalink: '/docs/hello',
slug: '/hello',
title: 'hello',
description: 'Hello 1.0.1 !',
version: '1.0.1',

View file

@ -71,6 +71,16 @@ export default function pluginContentDocs(
context: LoadContext,
options: PluginOptions,
): Plugin<LoadedContent | null, typeof PluginOptionSchema> {
// TODO remove homePageId before end of 2020
// "slug: /" is better because the home doc can be different across versions
if (options.homePageId) {
console.log(
chalk.red(
`The docs plugin option homePageId=${options.homePageId} is deprecated. To make a doc the "home", prefer frontmatter: "slug: /"`,
),
);
}
if (options.admonitions) {
options.remarkPlugins = options.remarkPlugins.concat([
[admonitions, options.admonitions],
@ -424,8 +434,10 @@ Available document ids=
const docsRoutes = await genRoutes(docs);
const mainDoc: Metadata =
docs.find((doc) => doc.unversionedId === options.homePageId) ??
docs[0];
docs.find(
(doc) =>
doc.unversionedId === options.homePageId || doc.slug === '/',
) ?? docs[0];
const toGlobalDataDoc = (doc: Metadata): GlobalDoc => ({
id: doc.unversionedId,

View file

@ -129,11 +129,13 @@ export default async function processMetadata({
throw new Error('Document id cannot include "/".');
}
const id =
dirNameWithVersion !== '.' ? `${dirNameWithVersion}/${baseID}` : baseID;
// test for website/docs folder, not a versioned folder
// TODO legacy test, looks bad
const isCurrrentDocs = dirNameWithVersion === '.';
const id = isCurrrentDocs ? baseID : `${dirNameWithVersion}/${baseID}`;
const unversionedId = version ? removeVersionPrefix(id, version) : id;
const isDocsHomePage = unversionedId === homePageId;
const isDocsHomePage = unversionedId === (homePageId ?? '_index');
if (frontMatter.slug && isDocsHomePage) {
throw new Error(
`The docs homepage (homePageId=${homePageId}) is not allowed to have a frontmatter slug=${frontMatter.slug} => you have to chooser either homePageId or slug, not both`,
@ -173,6 +175,7 @@ export default async function processMetadata({
title,
description,
source: aliasedSitePath(filePath, siteDir),
slug: docSlug,
permalink,
editUrl: custom_edit_url !== undefined ? custom_edit_url : docsEditUrl,
version,

View file

@ -12,12 +12,10 @@ import {
AdmonitionsSchema,
} from '@docusaurus/utils-validation';
const REVERSED_DOCS_HOME_PAGE_ID = '_index';
export const DEFAULT_OPTIONS: PluginOptions = {
path: 'docs', // Path to data on filesystem, relative to site dir.
routeBasePath: 'docs', // URL Route.
homePageId: REVERSED_DOCS_HOME_PAGE_ID, // Document id for docs home page.
homePageId: undefined, // TODO remove soon, deprecated
include: ['**/*.{md,mdx}'], // Extensions to include.
sidebarPath: '', // Path to sidebar configuration for showing a list of markdown pages.
docLayoutComponent: '@theme/DocPage',
@ -35,7 +33,7 @@ export const PluginOptionSchema = Joi.object({
path: Joi.string().default(DEFAULT_OPTIONS.path),
editUrl: Joi.string().uri(),
routeBasePath: Joi.string().allow('').default(DEFAULT_OPTIONS.routeBasePath),
homePageId: Joi.string().default(DEFAULT_OPTIONS.homePageId),
homePageId: Joi.string().optional(),
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
sidebarPath: Joi.string().default(DEFAULT_OPTIONS.sidebarPath),
docLayoutComponent: Joi.string().default(DEFAULT_OPTIONS.docLayoutComponent),

View file

@ -124,6 +124,7 @@ export interface MetadataRaw extends LastUpdateData {
title: string;
description: string;
source: string;
slug: string;
permalink: string;
sidebar_label?: string;
editUrl?: string | null;