Autogenerated navigation
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
.
Basic concept
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.md
If 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.md
JSON schema type hint
To 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"
}
]
// ...
}
Navbar level config
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/"
}
]
Sidebar level config
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;
file
- When the type is
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
.
- When the type is an object, you can describe it as a file, a directory or a custom link.
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"
}
dir
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
}
dir-section-header
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
}
divider
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.
section-header
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"
]
custom-link
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"
}
]
}
Complete example
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"
}
]
No config usage
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.md
In 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.md
Add SVG icons before titles
In 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.