跳到主要内容
版本:Canary 🚧

自动生成侧边栏

Docusaurus 可以根据你的文件系统结构自动生成侧边栏:每个文件夹会生成一个类别,每个文件会生成一个文档链接。

type SidebarItemAutogenerated = {
type: 'autogenerated';
dirName: string; // 生成侧边栏切片的源文件夹(相对文档目录)
};

Docusaurus 可以从你的 docs 文件夹中自动生成整个侧边栏:

sidebars.js
module.exports = {
myAutogeneratedSidebar: [
{
type: 'autogenerated',
dirName: '.', // '.' 即当前的文档文件夹
},
],
};

autogenerated 项目会被 Docusaurus 转换成一个侧边栏切片(这个概念在类别简写中也有涉及):一些 doccategory 类型的项目的列表。你可以在侧边栏的同一层中,把多个文件夹的多个 autogenerated 项目拼接在一起,并且和普通的侧边栏项目混合。

一个现实示例

考虑这个文件结构:

docs
├── api
│ ├── product1-api
│ │ └── api.md
│ └── product2-api
│ ├── basic-api.md
│ └── pro-api.md
├── intro.md
└── tutorials
├── advanced
│ ├── advanced1.md
│ ├── advanced2.md
│ └── read-more
│ ├── resource1.md
│ └── resource2.md
├── easy
│ ├── easy1.md
│ └── easy2.md
├── tutorial-end.md
├── tutorial-intro.md
└── tutorial-medium.md

假设每个文档的 ID 都只是它的文件名。 如果你像这么声明了自动生成侧边栏:

sidebars.js
module.exports = {
mySidebar: [
'intro',
{
type: 'category',
label: 'Tutorials',
items: [
'tutorial-intro',
{
type: 'autogenerated',
dirName: 'tutorials/easy', // 从 docs/tutorials/easy 生成侧边栏切片
},
'tutorial-medium',
{
type: 'autogenerated',
dirName: 'tutorials/advanced', // 从 docs/tutorials/hard 生成侧边栏切片
},
'tutorial-end',
],
},
{
type: 'autogenerated',
dirName: 'api', // 从 docs/api 生成侧边栏切片
},
{
type: 'category',
label: 'Community',
items: ['team', 'chat'],
},
],
};

It would be resolved as:

sidebars.js
module.exports = {
mySidebar: [
'intro',
{
type: 'category',
label: 'Tutorials',
items: [
'tutorial-intro',
// Two files in docs/tutorials/easy
'easy1',
'easy2',
'tutorial-medium',
// Two files and a folder in docs/tutorials/hard
'advanced1',
'advanced2',
{
type: 'category',
label: 'read-more',
items: ['resource1', 'resource2'],
},
'tutorial-end',
],
},
// Two folders in docs/api
{
type: 'category',
label: 'product1-api',
items: ['api'],
},
{
type: 'category',
label: 'product2-api',
items: ['basic-api', 'pro-api'],
},
{
type: 'category',
label: 'Community',
items: ['team', 'chat'],
},
],
};

Note how the autogenerate source directories themselves don't become categories: only the items they contain do. This is what we mean by "sidebar slice".

类别索引惯例

Docusaurus 可以自动给一个类别关联一篇索引文档。

类别索引文档的文件名符合下列条件之一:

  • 名为 index(大小写不敏感):docs/Guides/index.md
  • 名为 README(大小写不敏感):docs/Guides/README.mdx
  • 和上一级目录的名字一致:docs/Guides/Guides.md

这和一个带有文档链接的类别等价:

sidebars.js
module.exports = {
docs: [
{
type: 'category',
label: 'Guides',
link: {type: 'doc', id: 'Guides/index'},
items: [],
},
],
};
提示

把引言文档命名为 README.md,可以在 GitHub 上浏览此目录的时候显示这篇文档;用 index.md 则会更加接近服务器发送 HTML 文件的行为。

提示

如果一个文件夹只有一个索引页,它会变成一个链接,而不是一个类别。 这对于把资源和文档并置很有用:

some-doc
├── index.md
├── img1.png
└── img2.png
自定义类别索引匹配

你可以选择不使用三种类别索引惯例中的任何一种,或者也可以定义更多的惯例。 你可以通过 sidebarItemsGenerator 回调注入你自己的 isCategoryIndex 匹配函数。 比如,你可以选择 intro 文件名,让它也可能自动变成类别索引。

docusaurus.config.js
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
...args,
isCategoryIndex: defaultCategoryIndexMatcher, // 默认匹配函数实现,见下文
defaultSidebarItemsGenerator,
}) {
return defaultSidebarItemsGenerator({
...args,
isCategoryIndex(doc) {
return (
// 除了默认的文件名,也识别 intro.md
doc.fileName.toLowerCase() === 'intro' ||
defaultCategoryIndexMatcher(doc)
);
},
});
},
},
],
],
};

也可以选择不接受任何类别索引惯例。

docusaurus.config.js
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
...args,
isCategoryIndex: defaultCategoryIndexMatcher, // 默认匹配函数实现,见下文
defaultSidebarItemsGenerator,
}) {
return defaultSidebarItemsGenerator({
...args,
isCategoryIndex() {
// 没有文档会被自动选为类别索引
return false;
},
});
},
},
],
],
};

isCategoryIndex 匹配函数会接受一个有三个属性的对象:

  • fileName,不带扩展名的文件名,区分大小写
  • directories,一列从最底层到最高层的文件夹名,相对于文档根目录
  • extension,文件的扩展名,开头有一个点。

比如,对于一篇位于 guides/sidebar/autogenerated.md 的文档,匹配函数收到的参数会是:

const props = {
fileName: 'autogenerated',
directories: ['sidebar', 'guides'],
extension: '.md',
};

默认的匹配函数的实现是:

function isCategoryIndex({fileName, directories}) {
const eligibleDocIndexNames = [
'index',
'readme',
directories[0].toLowerCase(),
];
return eligibleDocIndexNames.includes(fileName.toLowerCase());
}

自动生成侧边栏元数据

对于手写的侧边栏定义,你会通过 sidebars.js 给每个项目提供元数据;对于自动生成的侧边栏,Docusaurus 会从项目对应的文件中读取。 除此之外,你还可能想要调整每个项目之间的相对位置,因为默认情况下,同一个侧边栏切片里的项目会根据文件和文件夹名字,按字母表顺序生成。

文档项目元数据

labelclassNamecustomProps 属性在前言中声明,对应的字段分别是 sidebar_labelsidebar_class_namesidebar_custom_props。 相对位置可以用一样的方法声明,也就是 sidebar_position 前言。

docs/tutorials/tutorial-easy.md
---
sidebar_position: 2
sidebar_label: 简单
sidebar_class_name: green
---

# 简单教程

这里是简单教程!

类别元数据

在类别相对应的文件夹里新建一个 _category_.json_category_.yml 文件。 你可以声明类别所需要的任何元数据,以及 position 元数据。 如果类别有文档索引链接,labelclassNamepositioncustomProps 会默认为此文档的对应元数据值。

docs/tutorials/_category_.json
{
"position": 2.5,
"label": "教程",
"collapsible": true,
"collapsed": false,
"className": "red",
"link": {
"type": "generated-index",
"title": "教程总览"
},
"customProps": {
"description": "这个描述可以用在 swizzle 的 DocCard 里"
}
}
信息

如果显式指定了一个 link,Docusaurus 就不会应用任何默认惯例

文档链接可以是相对的。比如,如果用 guides 目录生成类别,"link": {"type": "doc", "id": "intro"} 会被解析到 guides/intro 这个 ID,只有当前一个 ID 对应的文档不存在时,才会回退到 intro ID。

你也可以用 link: null 来防止 Docusaurus 应用任何惯例,从而让类别不带有索引页。

信息

位置元数据只会在一个侧边栏切片的内部使用:Docusaurus 不会重新排列你的侧边栏的其他项目。

使用数字前缀

有一种简单的给自动生成侧边栏排序的方法,就是给每个文档和文件夹添加一个数字前缀。这会让它们在文件系统按文件名排序时也是有序的:

docs
├── 01-Intro.md
├── 02-Tutorial Easy
│ ├── 01-First Part.md
│ ├── 02-Second Part.md
│ └── 03-End.md
├── 03-Tutorial Hard
│ ├── 01-First Part.md
│ ├── 02-Second Part.md
│ ├── 03-Third Part.md
│ └── 04-End.md
└── 04-End.md

为了更方便使用此功能,Docusaurus 支持多种数字前缀模式

默认情况下,Docusaurus 会从文档 ID、标签及 URL 路径中移除数字前缀

注意

我们推荐你使用额外的元数据

更新数字前缀很麻烦,因为可能需要更新多个已有的 Markdown 链接

docs/02-Tutorial Easy/01-First Part.md
- 看看[教程结语](../04-End.md);
+ 看看[教程结语](../05-End.md);

自定义侧边栏项生成器

你可以在文档插件(或预设)中提供自定义的 sidebarItemsGenerator 函数:

docusaurus.config.js
module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
defaultSidebarItemsGenerator,
numberPrefixParser,
item,
version,
docs,
categoriesMetadata,
isCategoryIndex,
}) {
// 示例:返回一列硬编码的静态侧边栏项目
return [
{type: 'doc', id: 'doc1'},
{type: 'doc', id: 'doc2'},
];
},
},
],
],
};
提示

重复利用并增强默认的生成器,而不是从零开始写一个生成器:我们提供的默认生成器有 250 行代码长。

根据你的需要,添加、更新、筛选、重新排序现有的侧边栏项:

docusaurus.config.js
// 反转侧边栏项的顺序(包括嵌套的类别项)
function reverseSidebarItems(items) {
// 反转类别的子项目
const result = items.map((item) => {
if (item.type === 'category') {
return {...item, items: reverseSidebarItems(item.items)};
}
return item;
});
// 反转当前层级的项目
result.reverse();
return result;
}

module.exports = {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({defaultSidebarItemsGenerator, ...args}) {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return reverseSidebarItems(sidebarItems);
},
},
],
],
};