In Rspress, in addition to declaring nav and sidebar in the configuration file, you can also automatically generate the navigation bar and sidebar by declaring the _nav.json and _meta.json description files. We recommend the latter because it can make the configuration file more concise and clear, and it includes all the capabilities under themeConfig.
Automated navbar/sidebar will only work if there are no nav and sidebar configurations in the config file rspress.config.ts.
Rspress generates the nav through _nav.json and the sidebar through _meta.json. The _nav.json at the navigation bar level is located in the root directory of the document, while the _meta.json at the sidebar level is located in the subdirectories of the document root. For example:
docs
βββ _nav.json // navigation bar level
βββ guides
βββ _meta.json // sidebar level
βββ introduction.mdx
βββ advanced
βββ _meta.json // sidebar level
βββ plugin-development.mdIf your document supports i18n, then _nav.json at the navigation bar level will be placed in the corresponding language directory, for example:
docs
βββ en
β βββ _nav.json // navigation bar level
β βββ guides
β βββ _meta.json // sidebar level
β βββ introduction.mdx
β βββ install.mdx
β βββ advanced
β βββ _meta.json // sidebar level
β βββ plugin-development.md
βββ zh
βββ _nav.json // navigation bar level
βββ guides
βββ _meta.json // sidebar level
βββ introduction.mdx
βββ install.mdx
βββ advanced
βββ _meta.json // sidebar level
βββ plugin-development.mdTo better edit _nav.json and _meta.json files, Rspress V2 provides two schema files @rspress/core/meta-json-schema.json and @rspress/core/nav-json-schema.json for IDE type hinting.
For example, in VSCode, you can add the following configuration in .vscode/settings.json:
{
//...
"json.schemas": [
{
"fileMatch": ["**/_meta.json"],
"url": "./node_modules/@rspress/core/meta-json-schema.json"
// or "url": "https://unpkg.com/@rspress/core@2.0.0-beta.21/meta-json-schema.json"
},
{
"fileMatch": ["**/_nav.json"],
"url": "./node_modules/@rspress/core/nav-json-schema.json"
// or "url": "https://unpkg.com/@rspress/core@2.0.0-beta.21/nav-json-schema.json"
}
]
// ...
}At the navigation bar level, you can fill in an array in _nav.json, and its type is exactly the same as the nav config of the default theme. For details, please refer to nav config. For example:
[
{
"text": "Guide",
"link": "/guides/introduction",
"activeMatch": "^/guides/"
}
]At the sidebar level, you can fill in an array in _meta.json, with each item of the following type:
export type FileSideMeta = {
type: 'file';
name: string;
label?: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
};
export type DirSideMeta = {
type: 'dir';
name: string;
label?: string;
collapsible?: boolean;
collapsed?: boolean;
tag?: string;
overviewHeaders?: number[];
context?: string;
};
export type DirSectionHeaderSideMeta = Omit<DirSideMeta, 'type'> &
Omit<SectionHeaderMeta, 'type'> & { type: 'dir-section-header' };
export type DividerSideMeta = {
type: 'divider';
dashed?: boolean;
};
export type SectionHeaderMeta = {
type: 'section-header';
label: string;
tag?: string;
};
export type CustomLinkMeta =
| {
// file link
type: 'custom-link';
label: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
link: string;
}
| {
// dir link
type: 'custom-link';
label: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
link?: string;
collapsible?: boolean;
collapsed?: boolean;
items: _CustomLinkMetaWithoutTypeField[];
};
export type SideMetaItem =
| FileSideMeta
| DirSideMeta
| DirSectionHeaderSideMeta
| DividerSideMeta
| SectionHeaderMeta
| CustomLinkMeta
| string;string, it means that the item is a file, and the file name is the string, for example:["introduction"]The file name may or may not have a suffix, for example introduction will be parsed as introduction.mdx.
In the case of describing file, the types are as follows:
export type FileSideMeta = {
type: 'file';
name: string;
label?: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
};Here, name means the file name, with or without a suffix is supported, label means the display name of the file in the sidebar. label is optional, if not filled, it will automatically take the h1 title in the document. overviewHeaders means the headers displayed in the overview page of the file. It is optional and the default value is [2]. context means adding the value of the data-context attribute to the DOM node when generating the sidebar, it is optional and will not be added by default. For example:
{
"type": "file",
"name": "introduction",
"label": "Introduction"
}In the case of describing directories, the types are as follows:
export type DirSideMeta = {
type: 'dir';
name: string;
label?: string;
collapsible?: boolean;
collapsed?: boolean;
tag?: string;
overviewHeaders?: number[];
context?: string;
};Here, name indicates the directory name, label indicates the display name of the directory in the sidebar, collapsible indicates whether the directory can be collapsed, collapsed indicates whether the directory is collapsed by default, and overviewHeaders indicates the headers displayed on the overview page for files in this directory. It is optional and the default value is [2]. context means adding the value of the data-context attribute to the DOM node when generating the sidebar, it is optional and will not be added by default. For example:
{
"type": "dir",
"name": "advanced",
"label": "Advanced",
"collapsible": true,
"collapsed": false
}When describing a directory, you can also use dir-section-header, which only differs from "type": "dir" in UI. It is often used at the first level, where the directory title is displayed as a section header and is at the same level as files under the directory.
Type:
export type DirSectionHeaderSideMeta = Omit<DirSideMeta, 'type'> &
Omit<SectionHeaderMeta, 'type'> & { type: 'dir-section-header' };{
"type": "dir-section-header",
"name": "advanced",
"label": "Advanced",
"collapsible": true,
"collapsed": false
}In the case of describing divider, the types are as follows:
export type DividerSideMeta = {
type: 'divider';
dashed?: boolean;
};When dashed is set to true, it indicates that the divider line is dashed. Otherwise, it is solid.
If you want to display a document when clicking on the sidebar directory, you can create an md(x) file with the same name at the same level as the current directory, for example:
docs
βββ advanced.mdx
βββ advanced
βββ _meta.json
βββ ...In this way, when you click on the Advanced directory, the content of the advanced.mdx file will be displayed.
In the case of describing section header, the type is as follows:
export type SectionHeaderMeta = {
type: 'section-header';
label: string;
tag?: string;
};Here, label represents the display name of this section header in the sidebar, for example:
{
"type": "section-header",
"label": "Section Header"
}This way, you can add section headers to the sidebar, which makes it easier to group documents and directories. Generally, you can use it in conjunction with divider to better distinguish different groups. For example:
[
{
"type": "section-header",
"label": "Section 1"
},
"introduction",
{
"type": "divider"
},
{
"type": "section-header",
"label": "Section 2"
},
"advanced"
]In the case of describing custom link, the types are as follows:
export type CustomLinkMeta =
| {
// file link
type: 'custom-link';
label: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
link: string;
}
| {
// dir link
type: 'custom-link';
label: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
link?: string;
collapsible?: boolean;
collapsed?: boolean;
items: _CustomLinkMetaWithoutTypeField[];
};Here, link indicates the link address, label indicates the display name of the link in the sidebar, for example:
{
"type": "custom-link",
"link": "/my-link",
"label": "My Link"
}link supports external links, for example:
{
"type": "custom-link",
"link": "https://github.com",
"label": "GitHub"
}You can also use items to create a nested custom link, for example:
{
"type": "custom-link",
"label": "My Link",
"items": [
{
"type": "custom-link",
"label": "Sub Link",
"link": "/sub-link"
}
]
}Here is a complete example using the three types above:
[
"install",
{
"type": "file",
"name": "introduction",
"label": "Introduction"
},
{
"type": "dir",
"name": "advanced",
"label": "Advanced",
"collapsible": true,
"collapsed": false
},
{
"type": "custom-link",
"link": "/my-link",
"label": "My Link"
}
]In some directories, you don't need to configure _meta.json and let Rspress automatically generate the sidebar. This requires ensuring that the directory contains only documents, not subdirectories, and you have no requirements for the order of documents. For example, there is now the following document structure:
docs
βββ _meta.json
βββ guides
βββ _meta.json
βββ basic
βββ introduction.mdx
βββ install.mdx
βββ plugin-development.mdIn the guides directory you can configure _meta.json as follows:
[
{
"type": "dir",
"name": "basic",
"label": "Basic",
"collapsible": true,
"collapsed": false
}
]In the basic directory, you may not configure _meta.json, and then Rspress will automatically generate a sidebar for you, the default is sorted alphabetically according to the file name. If you want to customize the order, you can prefix the file name with a number, such as:
basic
βββ 1-introduction.mdx
βββ 2-install.mdx
βββ 3-plugin-development.mdIn addition, you can add icons before the title through the tag config, like this:
{
"type": "file",
"name": "introduction",
"label": "Introduction",
"tag": "<svg width=\"1em\" height=\"1em\" viewBox=\"0 0 32 32\"><path fill=\"currentColor\" d=\"M4 6h24v2H4zm0 18h24v2H4zm0-12h24v2H4zm0 6h24v2H4z\"/></svg>"
}The value of tag is a svg tag string or image url, which you can configure in the navbar or sidebar.