> For AI agents: the complete documentation index is available at https://rspress.rs/zh/llms.txt, the full documentation bundle is available at https://rspress.rs/zh/llms-full.txt.

# 自动生成导航

在 Rspress 中，除了在配置文件中通过 `themeConfig` 声明 [nav](https://rspress.rs/zh/api/config/config-theme.md#nav) 和 [sidebar](https://rspress.rs/zh/api/config/config-theme.md#sidebar)，你也可以通过声明 `_nav.json` 和 `_meta.json` 描述文件来自动生成导航栏和侧边栏。我们更推荐后者，它能让配置文件更简洁，支持 HMR，同时仍包含 `themeConfig` 下的全部能力。

:::tip 提示
当配置文件 `rspress.config.ts` 中没有 `nav` 和 `sidebar` 配置的情况下，自动化导航栏/侧边栏才会生效。
:::

## 基本用法

Rspress 通过 `_nav.json` 生成导航栏，通过 `_meta.json` 生成侧边栏。导航级别的 `_nav.json` 位于文档根目录中，而侧边栏级别的 `_meta.json` 位于文档根目录的子目录中。比如:

```tree
docs
├── _nav.json // 导航栏级别
└── guide
    ├── _meta.json // 侧边栏级别
    ├── introduction.mdx
    └── advanced
        ├── _meta.json // 侧边栏级别
        └── plugin-development.md
```

如果你的文档使用了国际化，那么导航栏级别的 `_nav.json` 会放置在对应语言目录下，比如：

```tree
docs
├── en
│   ├── _nav.json // 导航栏级别
│   └── guide
│       ├── _meta.json // 侧边栏级别
│       ├── introduction.mdx
│       ├── install.mdx
│       └── advanced
│           ├── _meta.json // 侧边栏级别
│           └── plugin-development.md
└── zh
    ├── _nav.json // 导航栏级别
    └── guide
        ├── _meta.json // 侧边栏级别
        ├── introduction.mdx
        ├── install.mdx
        └── advanced
            ├── _meta.json // 侧边栏级别
            └── plugin-development.md
```

## 全局侧边栏用法

默认情况下（根目录仅存在 `_nav.json`），Rspress 会为每个子目录生成**独立的侧边栏**，侧边栏会根据当前激活的导航项自动切换。例如，点击「Guide」导航项会显示 Guide 的侧边栏，点击「API」则显示 API 的侧边栏：

```tree
docs
├── _nav.json
├── guide
│   ├── _meta.json  // /guide 的侧边栏
│   └── ...
└── api
    ├── _meta.json  // /api 的侧边栏
    └── ...
```

如果你希望所有页面**共用一个全局侧边栏**，而不是按导航项切换，可以在文档根目录下添加一个 `_meta.json`（与 `_nav.json` 同级）。

这种方式更适合**导航项较少、结构比较简单**的文档站点。因为无论用户当前位于哪个导航项下，侧边栏都保持一致，适合将整站内容统一组织在一个侧边栏中展示：

```tree
docs
├── _nav.json
├── _meta.json  // 根目录 _meta.json → 全局侧边栏
├── guide
│   ├── _meta.json
│   └── ...
└── api
    ├── _meta.json
    └── ...
```

当根目录存在 `_meta.json` 时，Rspress 会生成一个以 `'/'` 为键的全局侧边栏，无论当前激活的是哪个导航项，侧边栏内容都保持一致。根目录的 `_meta.json` 作为整个侧边栏树的入口，通常可以用分组标题的方式组织各个子目录：

```json title="docs/_meta.json"
[
  {
    "type": "dir-section-header",
    "name": "guide",
    "label": "Guide"
  },
  {
    "type": "dir-section-header",
    "name": "api",
    "label": "API"
  }
]
```

## JSON schema 类型提示

为了更好地编辑 `_nav.json` 和 `_meta.json` 文件，Rspress 提供了 `@rspress/core/meta-json-schema.json` 和 `@rspress/core/nav-json-schema.json` 两个 schema 文件用于 IDE 的类型提示。

以 VSCode 为例，可以在 `.vscode/settings.json` 中添加如下配置:

```json title=".vscode/settings.json"
{
  //...
  "json.schemas": [
    {
      "fileMatch": ["**/_meta.json"],
      "url": "./node_modules/@rspress/core/meta-json-schema.json"
      // 或者 "url": "https://unpkg.com/@rspress/core@2.0.0/meta-json-schema.json"
    },
    {
      "fileMatch": ["**/_nav.json"],
      "url": "./node_modules/@rspress/core/nav-json-schema.json"
      // 或者 "url": "https://unpkg.com/@rspress/core@2.0.0/nav-json-schema.json"
    }
  ]
  // ...
}
```

## 导航栏级别配置

在导航栏级别的情况中，你可以在 `_nav.json` 中填入一个数组，其类型跟默认主题的 nav 配置完全一致，详情可以参考 [nav 配置](https://rspress.rs/zh/api/config/config-theme.md#nav)。比如:

```json title="docs/_nav.json"
[
  {
    "text": "Guide",
    "link": "/guide/introduction",
    "activeMatch": "^/guide/"
  }
]
```

## 侧边栏级别配置

在侧边栏级别的情况中，你可以在 `_meta.json` 中填入一个数组，数组每一项的类型如下:

```ts
export type FileSideMeta = {
  type: 'file';
  name: string;
  label?: string;
  icon?: string;
  tag?: string;
  overviewHeaders?: number[];
  context?: string;
};

export type DirSideMeta = {
  type: 'dir';
  name: string;
  label?: string;
  collapsible?: boolean;
  collapsed?: boolean;
  icon?: string;
  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;
  icon?: string;
  tag?: string;
};

export type CustomLinkMeta =
  | {
      // file link
      type: 'custom-link';
      label: string;
      icon?: string;
      tag?: string;
      overviewHeaders?: number[];
      context?: string;
      link: string;
    }
  | {
      // dir link
      type: 'custom-link';
      label: string;
      icon?: 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

- 当类型为 `string` 时，表示该项是一个文件，文件名为该字符串，比如:

```json
["introduction"]
```

其中文件名可以带后缀，也可以不带后缀，比如 `introduction` 会被解析为 `introduction.mdx`。

- 当类型为对象形式时，你可以描述为一个文件、目录或者自定义链接。

在描述**文件**的情况下，类型如下:

```ts
export type FileSideMeta = {
  type: 'file';
  name: string;
  label?: string;
  icon?: string;
  tag?: string;
  overviewHeaders?: number[];
  context?: string;
};
```

其中，`name` 表示文件名，同时支持`带`/`不带`后缀，`label` 表示该文件在侧边栏中的显示名称，为可选值，如果未填则会自动取文档中的 h1 标题。`overviewHeaders` 表示该文件在 Overview 页中展示的标题级别，为可选值，默认为 `[2]`。`context` 表示在生成侧边栏时在所在的 DOM 节点添加 `data-context` 属性的值。为可选值，默认不会添加。比如:

```json
{
  "type": "file",
  "name": "introduction",
  "label": "Introduction"
}
```

### dir

在描述**目录**的情况下，类型如下:

```ts
export type DirSideMeta = {
  type: 'dir';
  name: string;
  label?: string;
  collapsible?: boolean;
  collapsed?: boolean;
  icon?: string;
  tag?: string;
  overviewHeaders?: number[];
  context?: string;
};
```

其中，`name` 表示目录名，`label` 表示该目录在侧边栏中的显示名称，`collapsible` 表示该目录是否可以折叠，`collapsed` 表示该目录是否默认折叠，`overviewHeaders` 表示该目录下的文件在 Overview 页中展示的标题级别，为可选值，默认为 `[2]`，即 h2。`context` 表示在生成侧边栏时在所在的 DOM 节点添加 `data-context` 属性的值。为可选值，默认不会添加。比如:

```json
{
  "type": "dir",
  "name": "advanced",
  "label": "Advanced",
  "collapsible": true,
  "collapsed": false
}
```

:::tip 提示

如果想要点击侧边栏目录显示某篇文档，推荐在目录内创建 `index.mdx` 文件，比如：

```tree
docs
└── basic
    ├── guide
    │   ├── index.mdx
    │   ├── getting-started.mdx
    │   └── _meta.json
    └── _meta.json
```

```json title="basic/_meta.json"
[{ "type": "dir", "name": "guide" }]
```

```json title="basic/guide/_meta.json"
["getting-started"]
```

意为侧边栏里仅含有 `getting-started` 这一篇文档，当你点击 `Guide` 目录时，会显示 `index.mdx` 文件的内容。

:::

### dir-section-header new
当描述**目录**时，你也可以使用 `dir-section-header`，它与 `"type": "dir"` 仅在 UI 上有所变化，常用于第一级别，目录标题会以 [分组标题](#section-header) 的形式展示，并与目录下的文件处于同一层级。

类型为：

```ts
export type DirSectionHeaderSideMeta = Omit<DirSideMeta, 'type'> &
  Omit<SectionHeaderMeta, 'type'> & { type: 'dir-section-header' };
```

```json
{
  "type": "dir-section-header",
  "name": "advanced",
  "label": "Advanced",
  "collapsible": true,
  "collapsed": false
}
```

### divider

在描述**分割线**的情况下，类型如下：

```ts
export type DividerSideMeta = {
  type: 'divider';
  dashed?: boolean;
};
```

`dashed` 为 `true` 时表示该分割线是虚线，否则是实线。

### section-header

在描述**分组标题**的情况下，类型如下:

```ts
export type SectionHeaderMeta = {
  type: 'section-header';
  label: string;
  icon?: string;
  tag?: string;
};
```

其中，`label` 表示该分组标题在侧边栏中的显示名称，比如:

```json
{
  "type": "section-header",
  "label": "Section Header"
}
```

这样，你可以在侧边栏中添加分组标题，方便对文档和目录进行分组。一般情况下，你可以配合 `divider` 使用，来更好的区分不同的分组。比如:

```json
[
  {
    "type": "section-header",
    "label": "Section 1"
  },
  "introduction",
  {
    "type": "divider"
  },
  {
    "type": "section-header",
    "label": "Section 2"
  },
  "advanced"
]
```

### custom-link

在描述**自定义链接**的情况下，类型如下:

```ts
export type CustomLinkMeta =
  | {
      // file link
      type: 'custom-link';
      label: string;
      icon?: string;
      tag?: string;
      overviewHeaders?: number[];
      context?: string;
      link: string;
    }
  | {
      // dir link
      type: 'custom-link';
      label: string;
      icon?: string;
      tag?: string;
      overviewHeaders?: number[];
      context?: string;
      link?: string;
      collapsible?: boolean;
      collapsed?: boolean;
      items: _CustomLinkMetaWithoutTypeField[];
    };
```

其中，`label` 表示该链接在侧边栏中的显示名称，`link` 表示该链接的跳转地址，比如:

```json
{
  "type": "custom-link",
  "label": "My Link",
  "link": "/my-link"
}
```

`link` 支持外部链接，比如:

```json
{
  "type": "custom-link",
  "link": "https://github.com",
  "label": "GitHub"
}
```

同时 custom-link 也支持嵌套链接，比如:

```json
{
  "type": "custom-link",
  "label": "My Link",
  "items": [
    {
      "type": "custom-link",
      "label": "Sub Link 1",
      "link": "/sub-link-1"
    },
    {
      "type": "custom-link",
      "label": "Sub Link 2",
      "link": "/sub-link-2"
    }
  ]
}
```

### 完整示例

下面是一个完整的示例，用到了上述的三种类型:

```json
[
  "install",
  {
    "type": "file",
    "name": "introduction",
    "label": "Introduction"
  },
  {
    "type": "dir",
    "name": "advanced",
    "label": "Advanced",
    "collapsible": true,
    "collapsed": false
  },
  {
    "type": "custom-link",
    "label": "My Link",
    "link": "/my-link"
  }
]
```

### 无配置用法

某些目录下你可以不配置 `_meta.json`，让 Rspress 自动帮你生成侧边栏。这需要保证目录下**仅包含文档，而不包含子目录**，并且你对**文档的顺序**没有要求。比如现在有如下的文档结构:

```tree
docs
├── _meta.json
└── guide
  ├── _meta.json
  └── basic
    ├── introduction.mdx
    ├── install.mdx
    └── plugin-development.md
```

在 `guide` 目录中你可以配置 `_meta.json` 内容如下:

```json
[
  {
    "type": "dir",
    "name": "basic",
    "label": "Basic",
    "collapsible": true,
    "collapsed": false
  }
]
```

而在 `basic` 目录中，你可以不配置 `_meta.json`，Rspress 会自动帮你生成侧边栏，默认按照文件名的字母顺序排序。如果你想要自定义顺序，可以在文件名前加上数字前缀，比如:

```tree
basic
  ├── 1-introduction.mdx
  ├── 2-install.mdx
  └── 3-plugin-development.md
```

## 使用 frontmatter 配置文件项

自动生成的文件项中，大部分展示字段都可以在页面 frontmatter 中配置，包括 `title`、`icon`、`tag`、`overviewHeaders` 和 `context`。

项目顺序、`type`、`name`、目录分组、分组标题、自定义链接、`collapsible` 和 `collapsed` 等结构性配置应保留在 `_meta.json` 中。对于页面自身的展示信息，推荐使用 frontmatter，让内容与对应的侧边栏配置保持在一起。

例如，可以在 `_meta.json` 中声明需要展示的文件及其顺序：

```json title="docs/guide/_meta.json"
["introduction"]
```

然后在页面 frontmatter 中配置文件项的展示信息：

```md title="docs/guide/introduction.mdx"
---
title: Introduction
icon: /icon.png
tag: new
overviewHeaders: [2, 3]
context: guide-introduction
---

# Introduction
```

当文件项在两处配置了同一个字段时，`icon`、`tag`、`overviewHeaders` 和 `context` 以 frontmatter 为准，而 `_meta.json` 中的 `label` 优先于页面标题。对于目录分组，`_meta.json` 的配置优先于目录首页的元数据。

## 侧边栏图标和标签

你可以通过 `icon` 配置在侧边栏标题前添加图标。最常用且推荐的方式是将图片放在 `public` 目录中，并通过绝对路径引用。

例如，将本地图片放在 `docs/public/icon.png`，然后在 `_meta.json` 中引用：

```json title="docs/_meta.json"
[
  {
    "type": "file",
    "name": "introduction",
    "label": "Introduction",
    "icon": "/icon.png",
    "tag": "new"
  }
]
```

如果希望将图标直接嵌入配置中，也可以传入一个内联 SVG 字符串：

```json title="docs/_meta.json"
[
  {
    "type": "file",
    "name": "introduction",
    "icon": "<svg width=\"1em\" height=\"1em\" viewBox=\"0 0 32 32\"><path fill=\"currentColor\" d=\"M4 6h24v2H4zm0 18h24v2H4zm0-12h24v2H4zm0 6h24v2H4z\"/></svg>"
  }
]
```

此外还支持 emoji、外链和 data URL。已有的 `tag` 配置仍显示在标题之后。

关于 `tag` 的详细用法请参考 [Tag 组件](https://rspress.rs/zh/ui/layout-components/tag.md)。
