自动生成
Docusaurus 可以从文件系统结构自动创建侧边栏:每个文件夹创建一个侧边栏类别,每个文件创建一个文档链接。
type SidebarItemAutogenerated = {
type: 'autogenerated';
dirName: string; // 生成侧边栏片段的源文件夹(相对于文档)
};
Docusaurus 可以从文档文件夹生成完整的侧边栏:
export default {
myAutogeneratedSidebar: [
{
type: 'autogenerated',
dirName: '.', // '.' 表示当前文档文件夹
},
],
};
一个 autogenerated
项目被 Docusaurus 转换为侧边栏片段(在类别简写中也有讨论):一个 doc
或 category
类型的项目列表,因此您可以在一个侧边栏级别中拼接多个 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 就是其文件名。如果您定义一个自动生成的侧边栏如下:
export default {
mySidebar: [
'intro',
{
type: 'category',
label: '教程',
items: [
'tutorial-intro',
{
type: 'autogenerated',
dirName: 'tutorials/easy', // 从 docs/tutorials/easy 生成侧边栏片段
},
'tutorial-medium',
{
type: 'autogenerated',
dirName: 'tutorials/advanced', // 从 docs/tutorials/advanced 生成侧边栏片段
},
'tutorial-end',
],
},
{
type: 'autogenerated',
dirName: 'api', // 从 docs/api 生成侧边栏片段
},
{
type: 'category',
label: '社区',
items: ['team', 'chat'],
},
],
};
它将被解析为:
export default {
mySidebar: [
'intro',
{
type: 'category',
label: '教程',
items: [
'tutorial-intro',
// docs/tutorials/easy 中的两个文件
'easy1',
'easy2',
'tutorial-medium',
// docs/tutorials/advanced 中的两个文件和一个文件夹
'advanced1',
'advanced2',
{
type: 'category',
label: 'read-more',
items: ['resource1', 'resource2'],
},
'tutorial-end',
],
},
// docs/api 中的两个文件夹
{
type: 'category',
label: 'product1-api',
items: ['api'],
},
{
type: 'category',
label: 'product2-api',
items: ['basic-api', 'pro-api'],
},
{
type: 'category',
label: '社区',
items: ['team', 'chat'],
},
],
};
请注意,自动生成的源目录本身不会成为类别:只有它们包含的项目会。这就是我们所说的"侧边栏片段"。
类别索引约定
Docusaurus 可以自动将类别链接到其索引文档。
类别索引文档是遵循以下文件名约定的文档:
- 命名为
index
(不区分大小写):docs/Guides/index.md
- 命名为
README
(不区分大小写):docs/Guides/README.mdx
- 与父文件夹同名:
docs/Guides/Guides.md
这相当于使用带有文档链接的类别:
export default {
docs: [
{
type: 'category',
label: '指南',
link: {type: 'doc', id: 'Guides/index'},
items: [],
},
],
};
将您的介绍性文档命名为 README.md
使其在使用 GitHub 界面浏览文件夹时显示,而使用 index.md
使行为更符合 HTML 文件的服务方式。
如果一个文件夹只有一个索引页面,它将被转换为链接而不是类别。这对于资源归置很有用:
some-doc
├── index.md
├── img1.png
└── img2.png
Customizing category index matching
It is possible to opt out any of the category index conventions, or define even more conventions. You can inject your own isCategoryIndex
matcher through the sidebarItemsGenerator
callback. For example, you can also pick intro
as another file name eligible for automatically becoming the category index.
export default {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
...args,
isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below
defaultSidebarItemsGenerator,
}) {
return defaultSidebarItemsGenerator({
...args,
isCategoryIndex(doc) {
return (
// Also pick intro.md in addition to the default ones
doc.fileName.toLowerCase() === 'intro' ||
defaultCategoryIndexMatcher(doc)
);
},
});
},
},
],
],
};
Or choose to not have any category index convention.
export default {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
...args,
isCategoryIndex: defaultCategoryIndexMatcher, // The default matcher implementation, given below
defaultSidebarItemsGenerator,
}) {
return defaultSidebarItemsGenerator({
...args,
isCategoryIndex() {
// No doc will be automatically picked as category index
return false;
},
});
},
},
],
],
};
The isCategoryIndex
matcher will be provided with three fields:
fileName
, the file's name without extension and with casing preserveddirectories
, the list of directory names from the lowest level to the highest level, relative to the docs root directoryextension
, the file's extension, with a leading dot.
For example, for a doc file at guides/sidebar/autogenerated.md
, the props the matcher receives are
const props = {
fileName: 'autogenerated',
directories: ['sidebar', 'guides'],
extension: '.md',
};
The default implementation is:
function isCategoryIndex({fileName, directories}) {
const eligibleDocIndexNames = [
'index',
'readme',
directories[0].toLowerCase(),
];
return eligibleDocIndexNames.includes(fileName.toLowerCase());
}
Autogenerated sidebar metadata
For handwritten sidebar definitions, you would provide metadata to sidebar items through sidebars.js
; for autogenerated, Docusaurus would read them from the item's respective file. In addition, you may want to adjust the relative position of each item because, by default, items within a sidebar slice will be generated in alphabetical order (using file and folder names).
Doc item metadata
The label
, className
, and customProps
attributes are declared in front matter as sidebar_label
, sidebar_class_name
, and sidebar_custom_props
, respectively. Position can be specified in the same way, via sidebar_position
front matter.
---
sidebar_position: 2
sidebar_label: Easy
sidebar_class_name: green
---
# Easy Tutorial
This is the easy tutorial!
Category item metadata
Add a _category_.json
or _category_.yml
file in the respective folder. You can specify any category metadata and also the position
metadata. label
, className
, position
, and customProps
will default to the respective values of the category's linked doc, if there is one.
- JSON
- YAML
{
"position": 2.5,
"label": "Tutorial",
"collapsible": true,
"collapsed": false,
"className": "red",
"link": {
"type": "generated-index",
"title": "Tutorial overview"
},
"customProps": {
"description": "This description can be used in the swizzled DocCard"
}
}
position: 2.5 # float position is supported
label: 'Tutorial'
collapsible: true # make the category collapsible
collapsed: false # keep the category open by default
className: red
link:
type: generated-index
title: Tutorial overview
customProps:
description: This description can be used in the swizzled DocCard
If the link
is explicitly specified, Docusaurus will not apply any default conventions.
The doc links can be specified relatively, e.g. if the category is generated with the guides
directory, "link": {"type": "doc", "id": "intro"}
will be resolved to the ID guides/intro
, only falling back to intro
if a doc with the former ID doesn't exist.
You can also use link: null
to opt out of default conventions and not generate any category index page.
The position metadata is only used within a sidebar slice: Docusaurus does not re-order other items of your sidebar.
Using number prefixes
A simple way to order an autogenerated sidebar is to prefix docs and folders by number prefixes, which also makes them appear in the file system in the same order when sorted by file name:
docs
├── 01-Intro.md
├── 02-Tutorial Easy
│ ├── 01-First Part.md
│ ├── 02-Second Part.md
│ └── 03-End.md
├── 03-Tutorial Advanced
│ ├── 01-First Part.md
│ ├── 02-Second Part.md
│ ├── 03-Third Part.md
│ └── 04-End.md
└── 04-End.md
To make it easier to adopt, Docusaurus supports multiple number prefix patterns.
By default, Docusaurus will remove the number prefix from the doc id, title, label, and URL paths.
Prefer using additional metadata.
Updating a number prefix can be annoying, as it can require updating multiple existing Markdown links:
- Check the [Tutorial End](../04-End.mdx);
+ Check the [Tutorial End](../05-End.mdx);
Customize the sidebar items generator
You can provide a custom sidebarItemsGenerator
function in the docs plugin (or preset) config:
export default {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({
defaultSidebarItemsGenerator,
numberPrefixParser,
item,
version,
docs,
categoriesMetadata,
isCategoryIndex,
}) {
// Example: return an hardcoded list of static sidebar items
return [
{type: 'doc', id: 'doc1'},
{type: 'doc', id: 'doc2'},
];
},
},
],
],
};
Re-use and enhance the default generator instead of writing a generator from scratch: the default generator we provide is 250 lines long.
Add, update, filter, re-order the sidebar items according to your use case:
// Reverse the sidebar items ordering (including nested category items)
function reverseSidebarItems(items) {
// Reverse items in categories
const result = items.map((item) => {
if (item.type === 'category') {
return {...item, items: reverseSidebarItems(item.items)};
}
return item;
});
// Reverse items at current level
result.reverse();
return result;
}
export default {
plugins: [
[
'@docusaurus/plugin-content-docs',
{
async sidebarItemsGenerator({defaultSidebarItemsGenerator, ...args}) {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return reverseSidebarItems(sidebarItems);
},
},
],
],
};