---
url: /guide/start/introduction.md
---
# Introduction
Rspress is a static site generator based on [Rsbuild](https://rsbuild.rs/), rendered with the React framework. It comes with a default documentation theme, and you can quickly build a documentation site with Rspress. You can also customize the theme to meet your personalized static site needs, such as blog sites, product homepages, etc. Of course, you can also integrate the corresponding plugins provided by the official to easily build component library documentation.
## Why Rspress
Rspress is designed around the following core features:
- **Build Performance**. Ensuring a fast enough startup speed brings a good development experience.
- **MDX Support**. Through MDX, we can conveniently reuse document fragments and render custom React components in documents.
- **Basic Capabilities of Documentation Site**. Including internationalization, multi-version support, full-text search, component library documentation, etc.
- **Extensibility**. Provides a built-in plugin system, supports extending Rspress through plugin API.
These also represent some core requirements for static site development. The following will introduce these aspects separately.
### Build performance
As the project becomes larger and larger, team members often worry about the lengthy project startup time, which negatively affects the development experience. The longer the project development time, the more obvious this deterioration of experience.
We couldn't help but start thinking, can we break the limitations of the current community tool chain, break through the performance bottleneck of the existing SSG framework, and achieve the effect of instant startup for most project scenarios?
Then, we continued to explore in this direction and finally achieved this effect on Rspress.
If there is only one most core optimization method, it is undoubtedly the `Rust Frontend Toolchain`. We mainly use the Rust toolchain in two performance-sensitive parts:
- Bundler. Traditional bundlers include webpack, Rollup, etc. For a front-end project, the bundler is the integration hub of various compilation tool chains. It is a very critical engineering capability and has a huge impact on project construction performance. Rspress uses Rspack developed by the team. Rspack is a Bundler based on Rust, with built-in multiple performance optimization methods, such as multi-threaded parallel compilation, incremental compilation, etc., which are 5 to 10 times more efficient than traditional packaging tools in the community.
- Markdown compiler. For another major compilation performance bottleneck in the SSG framework, namely `Markdown Compilation`, we also Rust this process to further speed up and customize Rspress's Markdown compiler (ie `@rspress/mdx-rs`). This compiler is nearly 20 times more efficient than the JS version of the compiler in the community:
At the same time, Rspress internally also applies many other build optimization methods, such as `pre-bundle of theme`, etc. These additional optimization methods, combined with the powerful Rust front-end toolchain, push the compilation performance of the SSG framework to a new height.
### MDX support
In order to ensure the flexibility of content development, Rspress chooses to support the MDX content format.
MDX represents a method of componentized content organization. In other words, documents serve as components, allowing for the reuse of document fragments across different documents. Additionally, custom React components can be incorporated into documents, significantly enhancing the flexibility of document development.
### Basic capabilities of documentation site
Of course, Rspress has also done a lot of work on the polishing of the basic capabilities of the documentation site, supporting the following functional features:
- Automatically generate layouts, including navigation bars, left sidebars, etc.
- Static site generation, HTML is directly output after production build.
- Internationalization, support for multi-language documents.
- Full-text search, provide out-of-the-box search function.
- Multi-version document management.
- Custom document theme.
- Automatically generate component Demo preview and playground.
In the following text, we will introduce these functional features in detail.
### Extension mechanism
Rspress internally designed various extension mechanisms to ensure sufficient customization capabilities, including:
- Support for custom global components, global styles, page layout structure, please refer to [Custom Page](/guide/basic/custom-page).
- Support **build extension**, including custom Rspack config, adding MDX compilation plugins, etc., please refer to [Build Extension](/guide/advanced/extend-build).
- Support **custom theme**, please refer to [Custom Theme](/ui/custom-theme).
- Built-in **plugin system**, support for custom plugins, please refer to [Plugin System](/plugin/system/introduction).
## Features
Next, let's introduce the main functional features of Rspress.
### Automatic layout generation
For the construction of a documentation site, in addition to displaying the main content, we generally need the following layout modules:
- Navigation bar, used to provide global navigation entrance.
- Sidebar, used to display the article directory under the current navigation.
- Article outline column, used to display the outline structure of the current page.
For the document outline, Rspress will automatically extract the various titles in the document, generate outline information, and display it on the right side of the article page by default, without any other operations.
For the navigation bar and sidebar, we provide two config methods, you can choose one of them:
- **Declarative config**. Configure the corresponding data by declaring `_meta.json` in the directory, such as:
```json title="_meta.json"
["introduction", "install", "start"]
```
You can read the [Auto Nav/Sidebar](/guide/basic/auto-nav-sidebar) for config details.
- **Programming config**. Implement it by specifying the [nav](/api/config/config-theme.html#nav) and [sidebar](/api/config/config-theme.html#sidebar) config items in the Rspress config.
We recommend using `declarative config` under normal scenes, which has many benefits:
1. Make config file is more concise and clear.
2. The correspondence between the `file directory structure` and the `sidebar directory structure` is more intuitive.
3. When adding or deleting a sidebar directory, operate directly in the current directory, instead of going to the `rspress.config.ts` config file to locate the corresponding position and then add/delete the config, thereby reducing the cost of switching development context.
The `programming config` is very useful in some scenarios where dynamic config generation is needed. For example, the official Rspress [TypeDoc plugin](/plugin/official-plugins/typedoc) will automatically convert a json data provided by TypeDoc into `nav` and `sidebar` configs.
### MDX support
MDX is a powerful content development format. You can not only write Markdown files as usual, but also use React components in the content of Markdown:
In addition, Rspress also supports some specific syntax, such as:
- Custom container syntax.
- FrontMatter metadata definition.
- Code line highlighting syntax.
Details can be found in the [Use MDX Document](/guide/use-mdx.html 'Use MDX s').
### SSG
Rspress is a SSG framework. In the build process in the production environment, it will automatically help you generate static sites, that is, generate HTML content for each page. After the build process is completed, HTML will appear in the default output directory.
Then, you can deploy the contents of this product directory to any static site hosting service, such as GitHub Pages, Netlify, Vercel, etc.
At the same time, we also provide config to easily customize the HTML content generated by SSG. For details, please refer to the [Static Site Generation Document](/guide/basic/ssg.html 'Static Site Generation Document').
### Internationalization (I18n)
Internationalization is a common requirement in a document-type site, and Rspress encapsulates the ability of internationalization to be simple and easy to use. In Rspress, we abstract internationalization into the following requirements:
- How to define I18n data source?
- How to configure the site under different languages?
- How to organize the document directory of different language versions?
- How to use I18n data source in custom components?
Rspress has already supported these demand scenarios for you. You can follow the [I18n Tutorial](/guide/default-theme/i18n.html 'I18n Tutorial') to step by step to implement internationalization for your site.
### Multi-version Documents
In some scenarios, we need to manage multi-version documents, and Rspress has built-in support for multi-version documents. On the one hand, you can enable this capability through simple config. On the other hand, you only need to organize the directory as usual, without introducing unnecessary directories and concepts, minimizing the mental burden:
```ts
// config file
import { defineConfig } from '@rspress/core';
export default defineConfig({
multiVersion: {
default: 'v1',
versions: ['v1', 'v2'],
},
});
```
```txt
// Directory structure
docs
├── v1
│ ├── README.md
│ └── guide
│ └── README.md
└── v2
├── README.md
└── guide
```
### Full text search
Rspress provides out-of-the-box full-text search capabilities, which you can access without any config. It is based on the open-source FlexSearch engine, with the following effect:
### Custom theme
Rspress supports two ways to customize themes:
1. Extend from the default theme. In each component of the default theme, many slots are provided for you to add custom layout content, for example:
```tsx
// theme/index.tsx
import Theme from '@rspress/core/theme';
import { NoSSR } from '@rspress/core/runtime';
const Layout = () => Custom Block
} />;
export default {
...Theme,
Layout,
};
export * from '@rspress/core/theme';
```
2. Fully customized theme. If you want to develop a custom theme from scratch, you can customize the content of Layout and use various Runtime APIs provided by Rspress (such as `usePageData`) to obtain compile-time data, routing information, etc.
For details about custom themes, you can refer to the [Custom Theme Documentation](/ui/custom-theme.html 'Custom Theme Documentation').
### Plugin system
The plugin system is a crucial part of Rspress, which can help you conveniently extend Rspress's functionality during site construction. Details can be found in the [Plugin Introduction Documentation](/plugin/system/introduction.html 'Introduction Documentation').
### Component documentation
#### Demo preview
Rspress provides a [preview plugin](/plugin/official-plugins/preview 'preview plugin'), which can automatically generate component previews for you. After you register the preview plugin, declare the following code block in the mdx file:
```tsx
import React from 'react';
import { Tag, Space } from '@arco-design/web-react';
import '@arco-design/web-react/dist/css/arco.css';
const COLORS = [
'red',
'orangered',
'orange',
'gold',
'lime',
'green',
'cyan',
'blue',
'arcoblue',
'purple',
'pinkpurple',
'magenta',
'gray',
];
export default () => {
return (
{COLORS.map((color, i) => (
{color}
))}
);
};
```
Then you can see the following preview effect:

Of course, the plugin also supports mobile preview mode, which you can enable through plugin config:

#### Demo real-time playground
For component documentation, if real-time editing capabilities can be provided for components, it will greatly enhance the interactive experience of the documentation.
To achieve this feature, you only need to register the official [playground plugin](/plugin/official-plugins/playground.html 'playground plugin'), and then declare your code block in the .mdx file. (Take the above code block as an example)
Next, you will see the following playground effect in the documentation:

### Built-in smooth transition animation
[View Transition API](https://developer.mozilla.org/zh-CN/docs/Web/API/View_Transitions_API 'View Transition API') is a set of APIs natively provided by modern browsers for implementing transition effects during page jumps. In Rspress, we also followed up on this feature, implemented document transition animations based on View Transition, and did not use any third-party SPA animation schemes. In the future, we will explore more animation effects to further enhance the experience.
```ts
export default defineConfig({
themeConfig: {
// Enable View Transition transition
enableContentAnimation: true,
enableAppearanceAnimation: true,
},
});
```
## Differences from other SSG frameworks
### Differences from Docusaurus
[Docusaurus](https://docusaurus.io/ 'Docusaurus') is an open-source SSG framework by Meta. Like Rspress, it uses React as the rendering framework and supports MDX. However, the main differences between Rspress and Docusaurus are:
1. Rspress uses [mdx-rs](https://github.com/web-infra-dev/mdx-rs) by default to provide better build performance. For details, see [Build Performance](#build-performance).
2. Rspress has simpler config and lower learning curve. Rspress's config is simpler, does not introduce too many concepts, and reduces cognitive load as much as possible. For example, it provides out-of-the-box search functionality, intuitive multi-version document management, etc.
3. Rspress provides a higher level of abstraction for Bundler in its architecture. For low-level Bundlers like webpack and Rspack, their config items are complex and not easy to get started with. Docusaurus chooses to directly expose the config items of the underlying Bundler, while Rspress provides a higher level of abstraction for Bundler, offering simpler and more user-friendly config items. For instance, you can easily add tags in `` through `builderConfig.html.tags`, without having to register related plugins via Bundler like `html-webpack-plugin`.
### Differences from Nextra
[Nextra](https://nextra.vercel.app/ 'Nextra') is an open-source SSG framework by Vercel. Like Rspress, it also uses React as the rendering framework and supports MDX. The main differences between Rspress and Nextra are:
1. Rspress has better build performance. This point can be referred to "Differences from Docusaurus".
2. Rspress is overall lighter. Nextra relies on Next.js, and its SSG process is also based on Next.js. Therefore, the SSG output is not purely HTML files, but includes some runtime code from Next.js. On one hand, this leads to a larger size of Nextra's output. On the other hand, it needs to be deployed as an application (using the `next start` command) rather than being deployed as a pure static site. But Rspress is not bound to any application framework, so its output is lighter and can be conveniently deployed as a pure static site.
### Differences from VitePress
[VitePress](https://vitepress.dev/ 'VitePress') is a static site generator based on Vite. It is characterized by using Vue as the rendering framework and has excellent performance. The main differences between Rspress and VitePress are:
1. Rspress uses React as the rendering framework, while VitePress uses Vue.
2. Rspress uses MDX for content development, while VitePress uses Markdown and supports Vue components in Markdown, which also leads to differences in the implementation of the underlying compilation toolchain.
3. In terms of build performance, during the development phase, both Rspress and VitePress can quickly start a project. However, in the production environment, VitePress needs to bundle the project based on Rollup, so it will face similar performance issues with other JavaScript-based toolchains. At this time, Rspress will have faster build speed.
## Try Rspress
Go to [Quick start](/guide/start/getting-started) to learn how to use Rspress to quickly build a documentation site.
---
url: /guide/start/getting-started.md
---
# Quick start
import { PackageManagerTabs } from '@theme';
## 1. Initialize the project
### Method 1: create via CLI
You can create a Rspress project using the `create-rspress` cli:
Input the project directory name, and then the cli will create the project for you.
### Method 2: manual creation
First, you can create a new directory with the following command:
```bash
mkdir rspress-app && cd rspress-app
```
Execute `npm init -y` to initialize a project. You can install Rspress using npm, pnpm, yarn or bun:
Then create the file with the following command
```bash
mkdir docs && echo '# Hello world' > docs/index.md
```
Add the following script to `package.json`:
```json
{
"scripts": {
"dev": "rspress dev",
"build": "rspress build",
"preview": "rspress preview"
}
}
```
Then initialize a configuration file `rspress.config.ts`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
root: 'docs',
});
```
And then create `tsconfig.json`, add the following config:
```json
{
"compilerOptions": {
"lib": ["DOM", "ES2020"],
"jsx": "react-jsx",
"target": "ES2020",
"noEmit": true,
"skipLibCheck": true,
"useDefineForClassFields": true,
/* modules */
"module": "ESNext",
"moduleDetection": "force",
"moduleResolution": "bundler",
"verbatimModuleSyntax": true,
"resolveJsonModule": true,
"allowImportingTsExtensions": true,
"noUncheckedSideEffectImports": true,
"isolatedModules": true,
/* type checking */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": ["docs", "theme", "rspress.config.ts"],
"mdx": {
"checkMdx": true
}
}
```
## 2. Start dev server
Start the local development service with the following command:
```bash
npm run dev
```
:::tip TIP
For the dev command, you can specify the port number or host of the development service with the `--port` or `--host` parameter, such as `rspress dev --port 8080 --host 0.0.0.0`.
:::
## 3. Build in production
Build the production bundle with the following command
:
```bash
npm run build
```
By default, Rspress will set `doc_build` as the output directory.
## 4. Preview in local environment
Start the local preview service with the following command:
```bash
npm run preview
```
---
url: /guide/basic/conventional-route.md
---
# Conventional route
## What is it?
Rspress uses file system routing, and the file path of the page is simply mapped to the routing path, which makes the routing of the entire project very intuitive.
For example, if there is a file named `foo.md` in the `docs` directory, the routing path for that file will be `/foo`.
## Mapping rules
Rspress automatically scans the root directory and all subdirectories, and maps file paths to route paths. For example, if you have the following file structure:
```txt
docs
├── foo
│ └── bar.md
└── foo.md
```
Then `bar.md` will be routed to `/foo/bar`, and `foo.md` will be routed to `/foo`.
The specific mapping rules are as follows:
| file path | route path |
| --------------- | ---------- |
| `index.md` | `/` |
| `/foo.md` | `/foo` |
| `/foo/bar.md` | `/foo/bar` |
| `/zoo/index.md` | `/zoo/` |
## Component routing
In conventional routing, in addition to `.md(x)` files, you can also use `.tsx` files as route components. By default, a component is exported in `.tsx`, and this component will be automatically registered in the route. For example:
```tsx title="foo.tsx"
export default () => {
return
foo
;
};
```
Of course, if you want to customize the layout, you can add an export to declare the layout type. For example:
```tsx title="foo.tsx"
export const frontmatter = {
// Declare layout type
// The custom layout here will not have a sidebar
pageType: 'custom',
};
```
For detailed meanings of each `pageType`, please refer to the [API documentation](/api/config/config-frontmatter#pagetype).
## Custom behavior
If you want to customize the routing behavior, you can use the `route` field in the configuration file. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
// These files will be excluded from the routing (support glob pattern)
exclude: ['component/**/*']
// These files will be included in the routing (support glob pattern)
include: ['other-dir/**/*'],
}
});
```
## Best practices
We recommend that you place documentation files in the `docs` directory to make your project more clear. For non-documentation content, such as custom components, util functions, etc., they can be maintained outside the `docs` directory. For example:
```txt
docs
└── foo.mdx
src
├── components
│ └── CustomComponent.tsx
└── utils
└── utils.ts
```
---
url: /guide/basic/auto-nav-sidebar.md
---
# Autogenerated navigation
In Rspress, in addition to declaring [nav](/api/config/config-theme.html#nav) and [sidebar](/api/config/config-theme.html#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`.
:::tip
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:
```txt
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:
```txt
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 title=".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.22/nav-json-schema.json"
}
]
}
```
## Navbar level config
In the case of 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](/api/config/config-theme.html#nav). for example:
```json title="docs/_nav.json"
[
{
"text": "Guide",
"link": "/guides/introduction",
"activeMatch": "^/guides/"
}
]
```
## Sidebar level config
In the case of the sidebar level, you can fill in `_meta.json` an array with each item of the following type:
```ts
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 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
| 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:
```json
["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:
```ts
export type FileSideMeta = {
type: 'file';
name: string;
label?: string;
tag?: string;
overviewHeaders?: number[];
context?: string;
};
```
Among them, `name` means the file name, `with`/`without` suffix is supported, `label` means the display name of the file in the sidebar.`label` is an optional value, if it is 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 an optional value 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 an optional value and will not be added by default. For example:
```json
{
"type": "file",
"name": "introduction",
"label": "Introduction"
}
```
### dir
In the case of describing **directories**, the types are as follows:
```ts
export type DirSideMeta = {
type: 'dir';
name: string;
label?: string;
collapsible?: boolean;
collapsed?: boolean;
tag?: string;
overviewHeaders?: number[];
context?: string;
};
```
Among them, `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 an optional value 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 an optional value and will not be added by default. For example:
```json
{
"type": "dir",
"name": "advanced",
"label": "Advanced",
"collapsible": true,
"collapsed": false
}
```
In the case of describing **divider**, the types are as follows:
```ts
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.
:::tip
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:
```txt
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:
```ts
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:
```json
{
"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:
```json
[
{
"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:
```ts
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[];
};
```
Among them, `link` indicates the link address, `label` indicates the display name of the link in the sidebar, for example:
```json
{
"type": "custom-link",
"link": "/my-link",
"label": "My Link"
}
```
`link` support external links, for example:
```json
{
"type": "custom-link",
"link": "https://github.com",
"label": "GitHub"
}
```
You can also use `items` to create a nested custom link, for example:
```json
{
"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:
```json
[
"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:
```txt
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:
```json
[
{
"type": "dir",
"name": "basic",
"label": "Basic",
"collapsible": true,
"collapsed": false
}
]
```
In `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:
```txt
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:
```json title="_meta.json"
{
"type": "file",
"name": "introduction",
"label": "Introduction",
"tag": ""
}
```
The value of `tag` is a svg tag string or image url, which you can configure in the **navbar** or **sidebar**.
---
url: /guide/basic/static-assets.md
---
# Static assets
## Introduction
In Rspress, you may use the following static assets:
- Logo image at the top left corner of the site
- Site favicon icon
- Homepage logo image
- Images, videos and other static assets used in .md(x) files
- Other static assets
Next, we will introduce how to use these static assets one by one.
:::tip Tip
The `document root directory` mentioned below refers to the directory specified by the `root` field in `rspress.config.ts`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
root: 'docs',
});
```
:::
## Top left corner logo
In Rspress, you can specify the logo image at the top left corner through the `logo` field. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
logo: 'https://avatars.githubusercontent.com/u/56892468?s=200&v=4',
});
```
The logo field supports both string and object configurations.
When the logo is a string, there are the following config situations:
- Configured as an **external link**, like the above example.
- Configured as an **absolute path**, such as `/rspress-logo.png`. In this case, Rspress will automatically find the `rspress-logo.png` image in the `public directory` of your **document root directory** and display it.
- Configured as a **relative path**, such as `./docs/public/rspress-logo.png`. In this case, Rspress will find the `rspress-logo.png` image based on the project root directory and display it.
If your website needs to adapt to dark mode, you can also use the object configuration of the logo, such as:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
logo: {
light: 'https://avatars.githubusercontent.com/u/56892468?s=200&v=4',
dark: 'https://avatars.githubusercontent.com/u/56892468?s=200&v=4',
},
});
```
Here, `light` represents the logo address in light mode, and `dark` represents the logo address in dark mode. Their configuration methods are consistent with the above string configuration.
## Favicon
In Rspress, you can specify the site's favicon icon through the `icon` field. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
icon: 'https://avatars.githubusercontent.com/u/56892468?s=200&v=4',
});
```
The icon field supports string or URL config, with the following specific ways:
- Configured as an **external link**, like the above example.
- Configured as an **absolute path**, such as `/favicon.ico`. In this case, Rspress will automatically find the `favicon.ico` icon in the `public directory` of your **document root directory** and display it.
- Configured as a **relative path**, such as `./docs/public/favicon.ico`. In this case, Rspress will find the `favicon.ico` icon based on the project root directory and display it.
- Configured as a `file://` protocol or `URL`, such as `file:///local_path/favicon.ico`. In this case, Rspress will use the local absolute path `/local_path/favicon.ico` icon directly and display it.
## Homepage logo
In the [frontmatter configuration](/api/config/config-frontmatter.html#hero) of the homepage, you can specify the homepage logo image through the `hero.image.src` field. For example:
```mdx title="index.mdx"
---
pageType: home
hero:
image:
src: 'https://avatars.githubusercontent.com/u/56892468?s=200&v=4'
alt: Rspress
---
```
Here, src is a string, supporting the following configurations:
- Configured as an **external link**, like the above example.
- Configured as an **absolute path**, such as `/rspress-logo.png`. In this case, Rspress will automatically find the `rspress-logo.png` image in the `public directory` of your **document root directory** and display it.
## Static assets used in .md(x) files
You can import static assets in `markdown` (or `mdx`) files. Both relative paths and absolute paths are supported. For example, if there is an image in the same directory as the markdown, you can reference it like this:
```mdx

```
Of course, you can also directly use the img tag in `.mdx` files:
```mdx
```
Rspress will automatically find the image based on the `.mdx` file path and image path, and respond to the browser.
On the other hand, you can also import static assets using absolute paths. In this case, Rspress will look for assets in the `public` folder under the `document root directory`.
For example, if the root directory is `docs` and the directory structure is as follows
```txt
docs
├── public
│ └── demo.png
├── index.mdx
```
In the above `index.mdx` file, you can reference `demo.png` like this:
```mdx

```
Or use an absolute path to reference:
```mdx

```
**A special case to note is that**, when your site is configured with a `base` path, if you want to use the `img` tag to introduce an absolute path, you need to use `normalizeImagePath` provided by `rspress/runtime` to manually add the `base` path to its src. Here is an example:
```tsx title="guide.mdx"
import { normalizeImagePath } from '@rspress/core/runtime';
;
```
Not only images, but you can also import videos, audios and other static assets in markdown files.
## Other static assets
In some scenarios, you may need to deploy certain specific static assets, such as adding the deployment configuration file `_headers` of `Netlify` to specify custom HTTP response headers.
In that case, you can directly put these static assets in the `public directory` of the document root directory (such as `docs`). During the project build process, Rspress will automatically **copy all assets in the public directory to the product directory**. In this way, the assets under public can be deployed to the server.
---
url: /guide/basic/custom-page.md
---
import { PackageManagerTabs } from '@theme';
# Customizing page
Rspress provides several ways for you to customize the content of your pages, including:
- Adding custom global components.
- Adding custom global styles.
- Customizing page layout structure.
## Custom global components
In some scenarios, you may need to add some custom global components to the page. Rspress provides a config item `globalUIComponents` to achieve this function.
### How to use
Add the following config in `rspress.config.ts`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
globalUIComponents: [path.join(__dirname, 'components', 'MyComponent.tsx')],
});
```
Each item of `globalUIComponents` can be a string, representing the file path of the component; or it can be an array, the first item is the file path of the component, and the second item is the props object of the component, such as:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
globalUIComponents: [
[
path.join(__dirname, 'components', 'MyComponent.tsx'),
{
foo: 'bar',
},
],
],
});
```
import GlobalUIComponents from '@en/fragments/global-ui-components';
## Custom styles
In some scenarios, you may need to add some global styles on top of the theme UI. Rspress provides a configuration item `globalStyles` to achieve this function.
### How to use
Add the following configuration in `rspress.config.ts`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
globalStyles: path.join(__dirname, 'styles/index.css'),
});
```
Then you can add the following code:
```css title="styles/index.css"
:root {
--rp-c-brand: #f00;
}
```
In this way, Rspress will automatically collect all global styles and merge them into the final style file.
Here are some commonly used global styles:
```css title="styles/index.css"
:root {
/* Modify theme color */
--rp-c-brand: #f00;
--rp-c-brand-dark: #ffa500;
--rp-c-brand-darker: #c26c1d;
--rp-c-brand-light: #f2a65a;
--rp-c-brand-lighter: #f2a65a;
/* Modify the width of the left sidebar */
--rp-sidebar-width: 280px;
/* Modify the width of the right outline column */
--rp-aside-width: 256px;
/* Modify the background of the code block title */
--rp-code-title-bg: rgba(250, 192, 61, 0.15);
/* Modify the background of the code block content */
--rp-code-block-bg: rgba(214, 188, 70, 0.05);
}
```
> If you want to know more about the internal global styles, you can check [vars.css](https://github.com/web-infra-dev/rspress/blob/main/packages/theme-default/src/styles/vars.css)
### Tailwind CSS
In order to get Tailwind CSS working with Rspress, you can use the following steps:
1. Install Tailwind CSS:
2. Create a `postcss.config.js` file containing `tailwindcss` plugin:
```js title="postcss.config.js"
module.exports = {
plugins: {
tailwindcss: {},
},
};
```
3. Create a `tailwind.config.js` file and make sure all the content files are included via `content`:
```js title="tailwind.config.js"
module.exports = {
content: ['./src/**/*.tsx', './docs/**/*.mdx'],
theme: {
extend: {},
},
plugins: [],
};
```
4. Include the Tailwind directives in your CSS styles file from [Custom Styles](#custom-styles):
```css title=styles/index.css
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
```
> For most up to date configuration, please refer to the official [Tailwind CSS documentation](https://tailwindcss.com/docs/installation/using-postcss).
## Custom layout structure
### Using pageType
Rspress provides a pageType configuration for you to customize the layout structure of the page.
Rspress's convention-based routing supports two types of routes, one is document routing, that is, pages written with md(x) files, and the other is component routing, that is, pages written with `.jsx/.tsx` files.
For the former, you can add the `pageType` field in the frontmatter to specify the layout structure of the page, such as:
```mdx title="foo.mdx"
---
pageType: custom
---
```
For the latter, you can add the following export to specify `pageType`:
```tsx title="foo.tsx"
export const frontmatter = {
// Declare layout type
pageType: 'custom',
};
```
pageType can be configured as the following values:
import PageType from '@en/fragments/page-type';
### Using fine-grained switches
In addition to the `pageType` page layout level configuration, Rspress also provides more fine-grained switches. You can configure other fields in the frontmatter. These fields and their meanings are as follows:
- `navbar`: Whether to display the top navigation bar. When you want to hide the top navigation bar, you can set it to `false`.
- `sidebar`: Whether to display the sidebar. When you want to hide the sidebar, you can set it to `false`.
- `outline`: Whether to display the outline column. When you want to hide the outline column, you can set it to `false`.
- `footer`: Whether to display the footer. When you want to hide the footer, you can set it to `false`.
Example:
```mdx title="foo.mdx"
---
navbar: false
sidebar: false
outline: false
footer: false
globalUIComponents: false
---
```
### Using URL parameters as switches
In addition, you can use URL parameters to control the layout structure of the page at runtime, such as:
```bash
# Hide the navigation bar and outline in the right column
http://YOUR_DOMAIN/foo?navbar=0&outline=0
```
With URL parameters, you can quickly adjust the layout structure of the page without modifying the source code. These parameters specifically include:
- `navbar`: Whether to display the navigation bar. When you want to hide the top navigation bar, you can set it to `0`.
- `sidebar`: Whether to display the sidebar. When you want to hide the sidebar, you can set it to `0`.
- `outline`: Whether to display the outline column. When you want to hide the outline column, you can set it to `0`.
- `footer`: Whether to display the footer. When you want to hide the footer, you can set it to `0`.
- `globalUIComponents`: Whether to display the global components. When you want to hide the global components, you can set it to `0`.
## Custom tags
### Customizing head tag
In `rspress.config.ts`, you can custom HTML's metadata (aka head tag) for all pages. We explain it with more details in [basic config - head](/api/config/config-basic#head) within the api section.
### Generate metadata tags
Within frontmatter, you can also customize your page's metadata tag for SEO optimization.
For example, if you want to add `` in your `` tag, you can use frontmatter like so:
```md title="example.mdx"
---
head:
- - meta
- name: title
content: This is title
- - meta
- name: description
content: This is description
---
```
### Open Graph tags
[Open Graph](https://ogp.me/) is a web metadata protocol used to control how pages are displayed when shared on social media platforms.
Rspress automatically injects the following Open Graph meta tags for each page:
- `og:type`: Fixed value of `website`
- `og:title`: Automatically uses the current page's title
If you need to customize more Open Graph tags (such as `og:image`, `og:title`, etc.), please refer to [frontmatter configuration](/api/config/config-frontmatter#head).
---
url: /guide/basic/ssg.md
---
# Static site generation
## Introduction
In the production build, Rspress will automatically generate a static site for you, that is, generate the HTML content of each page. After the build is completed, the HTML will appear in the default product directory, such as:
```txt
doc_build
├── static # Static resources
│ ├── main.js
│ └── ...
├── index.html # Home page
├── about.html # About page
├── posts
│ ├── hello-world.html # Article page
│ └── ...
```
You can deploy the contents of this product directory to any static site hosting service, such as GitHub Pages, Netlify, Vercel, etc.
## Advantages of SSG
The essence of static site generation is to pre-render components at the build stage, render the components into HTML strings, and then write them into HTML files. This has many benefits, such as:
- Faster FCP, because there is no need to wait for JS to load before rendering.
- More conducive to SEO, because search engine spiders can directly crawl the complete HTML content.
Considering the cost of static site generation, Rspress only pre-renders during production environment builds. In the development environment, it still uses the traditional SPA rendering mode without pre-rendering.
## Adding custom site content
Through `builderConfig.html.tags`, you can customize the site HTML content, such as adding statistical code, adding scripts and styles, etc.
```js title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
// ...
builderConfig: {
html: {
tags: [
{
tag: 'script',
attrs: {
src: 'https://cdn.example.com/your-script.js',
},
},
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://cdn.example.com/your-style.css',
},
},
],
},
},
});
```
For more detailed config of `builderConfig.html.tags`, please refer to the [documentation](https://rsbuild.rs/config/html/tags).
## Preview
After the production build is complete, you can preview the output by using the `rspress preview` command. This command will start a local static site service, and you can access this service in your browser to preview the output.
```shell
> rspress preview
Preview server running at http://localhost:4173/
```
## Disabling SSG
If you do not want to use Static Site Generation, you can disable it through the `ssg` config.
```js title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
// ...
ssg: false,
});
```
:::warning
Please be cautious when disabling SSG, as this will forfeit many of the advantages of Static Site Generation mentioned above.
:::
---
url: /guide/basic/deploy.md
---
# Deployment
In this section, we will discuss the deployment of the project. We assume that you have completed the development of the project and now need to deploy the project online. You need to consider the following aspects:
- Production build and preview of the project.
- Static resource prefix configuration.
- Project base path configuration.
- Choose deployment platform for deployment.
## Build and preview
Before deployment, we need to first build the project in the production environment and preview it locally to ensure that the project can run normally. In Rspress projects, we can use the following `scripts` commands to build and preview:
```json
{
"scripts": {
"build": "rspress build",
"preview": "rspress preview"
}
}
```
:::tip Tip
For the preview command, you can specify the preview port number through the `--port` parameter, such as `rspress preview --port 8080`.
:::
It is worth noting that the final output will be output to the `doc_build` directory under the project root directory. The content in this directory is what we need to deploy.
## Static resource prefix configuration
We can divide the deployment output into two parts: HTML files and static resources. HTML files refer to the HTML files in the output directory. These files are the files we finally deploy to the server.
The so-called static resources refer to the `static` directory in the output directory, which contains the JavaScript, CSS, images and other static resources required by the project. When deploying, if you want to put these static resources on the CDN to ensure better access performance, instead of directly putting them on the server like HTML, then you need to configure the prefix of the static resources so that the project can correctly reference these static resources. You can complete it through `builderConfig.output.assetPrefix`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
builderConfig: {
output: {
assetPrefix: 'https://cdn.com/',
},
},
});
```
In this way, when referencing static resources in HTML, the prefix will be automatically added, for example:
```html
```
## Project base path configuration
When deploying, we may need to deploy the project to a subpath. For example, if you plan to deploy your site to `https://foo.github.io/bar/`, then you should set the `base` parameter to `"/bar/"`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
base: '/bar/',
});
```
## Deployment in platform
After completing the above configuration, we can deploy the output to the server. You have many choices, such as `Zephyr`, `GitHub Pages`, `Netlify`, `Vercel`, etc. Here we take `Zephyr`, `GitHub Pages` and `Netlify` as examples to explain how to deploy.
### Deploy with Zephyr Cloud
[Zephyr Cloud](https://zephyr-cloud.io) is a zero-config deployment platform that integrates directly into your build process and provides global edge distribution.
#### How to deploy
Follow the steps in [zephyr-rspress-plugin](https://www.npmjs.com/package/zephyr-rspress-plugin).
During the build process, your Rspress documentation site will be automatically deployed and you'll receive a deployment URL.
Zephyr Cloud handles asset optimization, global CDN distribution, and provides automatic rollback capabilities for your documentation sites.
### Deploy via GitHub actions
If your project is hosted on `GitHub`, then you can deploy via `GitHub Pages`. `GitHub Pages` is a static website hosting service provided by `GitHub`, which allows you to directly deploy your project to `GitHub` without having to build your own server.
#### 1. Create workflow file
First, you need to create a file named `.github/workflows/deploy.yml` in the project root directory, with the following content:
```yml
name: Deploy Rspress site to Pages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
- uses: pnpm/action-setup@v3 # pnpm is optional but recommended, you can also use npm / yarn
with:
version: 8
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Install dependencies
run: pnpm install
- name: Build with Rspress
run: |
pnpm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: doc_build
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
#### 2. Configure GitHub Actions
In the `Pages` column of the repository `Settings` interface, you can choose `GitHub Actions` as the deployment source.
#### 3. Push code to main branch
When you push the code to the `main` branch, `GitHub Actions` will automatically execute the deployment process. You can view the progress of the deployment in the `Actions` column. After the deployment is complete, you can access your site through `https://.github.io//`.
### Deploy via Netlify
`Netlify` is a Web application deployment platform, which allows you to directly deploy your project to `Netlify` without having to build your own server.
#### Basic configuration
Deploying a project on `Netlify` is very simple. You only need to import your GitHub repository, and then configure some basic information to deploy. Just configure the following two fields:
- `Build command`: Build command, here we fill in the build command in the project, such as `npm run build`.
- `Publish directory`: Output directory, here we fill in the output directory `doc_build` in the project.
Then click the `Deploy site` button to complete the deployment.
#### Configure custom domain
If you want to bind your site to your own domain, you can configure it in the `Domain management` column of `Netlify`. The specific configuration method can refer to the [Netlify official documentation](https://docs.netlify.com/domains-https/custom-domains/).
### Deploy to Kinsta static site hosting
You can deploy your Rspress site on [Kinsta](https://kinsta.com/static-site-hosting/).
1. Login or create an account to view your [MyKinsta](https://my.kinsta.com/) dashboard.
2. Authorize Kinsta with your Git provider.
3. Select **Static Sites** from the left sidebar and press **Add sites**.
4. Select the repository and branch you want to deploy.
5. During the build settings, Kinsta will automatically try to fill out the **Build command**, **Node version**, and **Publish directory**. If it won't, fill out the following:
- Build command: `npm run build`
- Node version: `18.16.0`
- Publish directory: `doc_build`
6. Click the **Create site**.
### Deploy to Zeabur
[Zeabur](https://zeabur.com) is a platform for deploying services instantly, which allows you to directly deploy your Rspress site without any other configurations.
#### How to deploy
First of all, you need to [create a Zeabur account](https://zeabur.com). Then, follow the instructions to create a project and install a GitHub app to authorize Zeabur get your Rspress repository.
Click on `Deploy New Service` and import your Rspress repository, the deployment will be started automatically and Zeabur will recognize that your site is built with Rspress.
The deployment will be finished in a minute, you can also bind a free sub domain provided by Zeabur or your own domain for this site.
---
url: /guide/use-mdx/index.md
---
# Use MDX
Rspress supports [MDX](https://mdxjs.com/), a powerful way to develop content.
## Markdown
MDX is a superset of Markdown, which means you can write Markdown files as usual. For example:
```md
# Hello world
```
## Customizing anchor id
By default, Rspress will automatically generate ids based on the content of each title. This id will also serve as the content of the anchor. You can use the following syntax to customize the id of the header:
```md
## Hello world {#custom-id}
```
Where `custom-id` is your custom id.
---
url: /guide/use-mdx/code-blocks.md
---
import { Tabs, Tab } from '@theme';
# Code blocks
Rspress V2 uses [Shiki](https://shiki.style) for syntax highlighting at compile time, which means better runtime performance.
When using code blocks in multiple languages, the corresponding language is automatically detected at compile time, and the runtime bundle size does not increase. For supported programming languages, refer to the [Shiki supported languages list](https://shiki.style/languages).
## Basic usage
You can use the \`\`\` syntax to create code blocks. For example:
````mdx
```js
console.log('Hello World');
```
````
It will be rendered as:
```js
console.log('Hello World');
```
## Code block title
You can use the `title="..."` attribute to add a title to a code block.
````mdx
```jsx title="src/components/HelloCodeBlockTitle.tsx"
const HelloCodeBlockTitle = (props) => {
return
Hello CodeBlock Title
;
};
```
````
It will be rendered as:
```jsx title="src/components/HelloCodeBlockTitle.tsx"
const HelloCodeBlockTitle = (props) => {
return
Hello CodeBlock Title
;
};
```
## External file code block
You can use the `file="./path/to/file"` attribute without writing any code block content to reference the text from an external file.
````mdx
```tsx file="./_tsx-component.tsx"
```
````
```tsx file="./_tsx-component.tsx"
```
It will be rendered as:
```tsx file="./_tsx-component.tsx"
```
:::tip
When using external file code blocks, it's common to use them together with [route conventions](./components.mdx#route-convention). Name files starting with `_`.
:::
## Notation line highlight
You can use [Shiki transformers](#shiki-transformers) with the `transformerNotationHighlight` and `// [!code highlight]` comments to highlight code lines.
````mdx
```ts
console.log('Highlighted'); // [\!code highlight]
console.log('Not highlighted');
// [\!code highlight:2]
console.log('Highlighted');
console.log('Highlighted');
```
````
```ts
import { defineConfig } from '@rspress/core';
import { transformerNotationHighlight } from '@shikijs/transformers';
export default defineConfig({
markdown: {
shiki: {
transformers: [transformerNotationHighlight()],
},
},
});
```
It will be rendered as:
```ts title="highlight.ts"
console.log('Highlighted'); // [!code highlight]
console.log('Not highlighted');
// [!code highlight:2]
console.log('Highlighted');
console.log('Highlighted');
```
:::warning
The backslash (`\`) in `[\!code highlight]` is for escaping in Markdown to show the original syntax. Do not include the backslash when actually using this syntax.
:::
## Meta line highlight
:::warning
When using meta info for line highlighting, be aware that formatting tools may change line numbers. For maintainability, [Notation Line Highlight](#notation-line-highlight) is recommended.
:::
You can use `@rspress/core/shiki-transformers` with `transformerCompatibleMetaHighlight` and meta info comments to highlight code lines.
````mdx
```ts {1,3-4}
console.log('Highlighted');
console.log('Not highlighted');
console.log('Highlighted');
console.log('Highlighted');
```
````
```ts
import { defineConfig } from '@rspress/core';
import { transformerCompatibleMetaHighlight } from '@rspress/core/shiki-transformers';
export default defineConfig({
markdown: {
shiki: {
transformers: [transformerCompatibleMetaHighlight()],
},
},
});
```
It will be rendered as:
```ts {1,3-4}
console.log('Highlighted');
console.log('Not highlighted');
console.log('Highlighted');
console.log('Highlighted');
```
### Show code line numbers
If you want to show code line numbers, you can enable the `showLineNumbers` option in the config file:
```ts title="rspress.config.ts"
export default {
// ...
markdown: {
showLineNumbers: true,
},
};
```
### Wrap code
If you want to enable long code wrapping by default, you can enable the `defaultWrapCode` option in the config file:
```ts title="rspress.config.ts"
export default {
// ...
markdown: {
defaultWrapCode: true,
},
};
```
## Diff code block
````mdx
```diff
function test() {
- console.log('deleted');
+ console.log('added');
console.log('unchanged');
}
```
````
It will be rendered as:
```diff
function test() {
- console.log('deleted');
+ console.log('added');
console.log('unchanged');
}
```
## Shiki transformers
Rspress V2 uses [Shiki](https://shiki.style) for compile-time code highlighting, providing flexible code block capabilities.
You can add custom [shiki transformers](https://shiki.style/guide/transformers.html) via [`markdown.shiki.transformers`](../../../api/config/config-build.mdx#markdownshiki) for richer code block effects.
In addition to the [transformerNotationHighlight](#notation-line-highlight) mentioned above, Rspress defaults to supporting the following transformers from [@shikijs/transformers](https://shiki.style/packages/transformers).
### transformerNotationDiff
````mdx
```ts
console.log('deleted'); // [\!code --]
console.log('added'); // [\!code ++]
console.log('unchanged');
```
````
```ts
import { defineConfig } from '@rspress/core';
import { transformerNotationDiff } from '@shikijs/transformers';
export default defineConfig({
markdown: {
shiki: {
transformers: [transformerNotationDiff()],
},
},
});
```
It will be rendered as:
```ts
console.log('deleted'); // [!code --]
console.log('added'); // [!code ++]
console.log('unchanged');
```
### transformerNotationErrorLevel
````mdx
```ts
console.log('No errors or warnings');
console.error('Error'); // [\!code error]
console.warn('Warning'); // [\!code warning]
```
````
```ts
import { defineConfig } from '@rspress/core';
import { transformerNotationErrorLevel } from '@shikijs/transformers';
export default defineConfig({
markdown: {
shiki: {
transformers: [transformerNotationErrorLevel()],
},
},
});
```
It will be rendered as:
```ts
console.log('No errors or warnings');
console.error('Error'); // [!code error]
console.warn('Warning'); // [!code warning]
```
### transformerNotationFocus
````mdx
```ts
console.log('Not focused');
console.log('Focused'); // [\!code focus]
console.log('Not focused');
```
````
```ts
import { defineConfig } from '@rspress/core';
import { transformerNotationFocus } from '@shikijs/transformers';
export default defineConfig({
markdown: {
shiki: {
transformers: [transformerNotationFocus()],
},
},
});
```
It will be rendered as:
```ts
console.log('Not focused');
console.log('Focused'); // [!code focus]
console.log('Not focused');
```
## Twoslash
> [Twoslash](https://twoslash.netlify.app/guide/) is a markup format for TypeScript code, suitable for creating self-contained code samples and letting the TypeScript compiler automatically supplement type information and hints. It is widely used on the official TypeScript website.
Rspress provides the `@rspress/core/plugin-twoslash` plugin, which enables Twoslash features in Rspress. See [@rspress/plugin-twoslash documentation](../../../plugin/official-plugins/twoslash.mdx) for details.
```ts twoslash
// @noErrorValidation
const str: string = 1;
```
## Runtime syntax highlighting
When you need to render code blocks dynamically at runtime, such as in interactive docs or fetching code remotely, Rspress provides the `CodeBlockRuntime` component.
Here is an example:
```mdx title="foo.mdx"
import { CodeBlockRuntime } from '@theme';
import { transformerNotationHighlight } from '@shikijs/transformers';
```
import { CodeBlockRuntime } from '@theme';
import { transformerNotationHighlight } from '@shikijs/transformers';
:::warning
It is recommended to use `CodeBlockRuntime` only when necessary, as it increases runtime bundle size and cannot benefit from compile-time highlighting performance.
:::
---
url: /guide/use-mdx/link.md
---
# Links
## Link format
Rspress supports two formats of links: **file path format** and **URL format**. They render exactly the same results, differing only in code style.
import { Tabs, Tab } from '@theme';
```mdx
[File path format - ../start/getting-started.mdx](../start/getting-started.mdx)
[URL format - /guide/start/getting-started](/guide/start/getting-started)
```
[File path format - ../start/getting-started.mdx](../start/getting-started.mdx)
[URL format - /guide/start/getting-started](/guide/start/getting-started)
:::tip
Within the same Rspress project, it is recommended to use only one type of link format to maintain consistent code style.
:::
## File path format
The file path format uses **absolute file paths** or **relative file paths** to reference specific `.md` or `.mdx` files.
Here are examples from this website:
```mdx
[Relative path - ../start/getting-started.mdx](../start/getting-started.mdx)
[Absolute path - /guide/start/getting-started.mdx](/guide/start/getting-started.mdx)
[Absolute path with language - /zh/guide/start/getting-started.mdx](/zh/guide/start/getting-started.mdx)
[Absolute path to another language page - /en/guide/start/getting-started.mdx](/en/guide/start/getting-started.mdx)
```
[Relative path - ../start/getting-started.mdx](../start/getting-started.mdx)
[Absolute path - /guide/start/getting-started.mdx](/guide/start/getting-started.mdx)
[Absolute path with language - /zh/guide/start/getting-started.mdx](/zh/guide/start/getting-started.mdx)
[Absolute path to another language page - /en/guide/start/getting-started.mdx](/en/guide/start/getting-started.mdx)
:::tip
When using absolute paths, the root path is the [`docs`](/api/config/config-basic#root) directory. If the project uses [internationalization](/guide/default-theme/i18n) or [multi-version](/guide/default-theme/multi-version), the [`markdown.link.autoPrefix`](/api/config/config-build#markdownlinkautoPrefix) configuration will automatically add prefixes, so you can omit the language directory in links.
For example:
[Absolute path - /guide/start/getting-started.mdx](/guide/start/getting-started.mdx)
[Absolute path with language - /zh/guide/start/getting-started.mdx](/zh/guide/start/getting-started.mdx)
Both will point to the same page.
:::
We recommend using relative file paths as they have the following advantages:
1. IDE support: hint, jump to the corresponding file, auto-update file links when moving files, etc.
2. Supported by GitHub interface and other Markdown editors.
3. Compared to URL format, you don't need to consider the impact of the [`cleanUrls`](/api/config/config-basic#routecleanurls) configuration.
## URL format
The URL format uses complete URL addresses to reference specific pages.
Here are examples from this website:
```mdx
[Relative path - ../start/getting-started](../start/getting-started)
[Absolute path - /guide/start/getting-started](/guide/start/getting-started)
[Absolute path - /guide/start/getting-started.html](/guide/start/getting-started.html)
[Absolute path with language - /zh/guide/start/getting-started.html](/zh/guide/start/getting-started.html)
[Absolute path to another language page - /en/guide/start/getting-started.html](/en/guide/start/getting-started.html)
```
[Relative path - ../start/getting-started](../start/getting-started)
[Relative path - ../start/getting-started.html](../start/getting-started.html)
[Absolute path - /guide/start/getting-started](/guide/start/getting-started)
[Absolute path - /guide/start/getting-started.html](/guide/start/getting-started.html)
[Absolute path with language - /zh/guide/start/getting-started.html](/zh/guide/start/getting-started.html)
[Absolute path to another language page - /en/guide/start/getting-started.html](/en/guide/start/getting-started.html)
:::tip
When using absolute paths, the root path is the [`docs`](/api/config/config-basic#root) directory. If the project uses [internationalization](/guide/default-theme/i18n) or [multi-version](/guide/default-theme/multi-version), the [`markdown.link.autoPrefix`](/api/config/config-build#markdownlinkautoPrefix) configuration will automatically add prefixes, so you can omit the language directory in links.
For example:
[Absolute path - /guide/start/getting-started](/guide/start/getting-started)
[Absolute path with language - /zh/guide/start/getting-started](/zh/guide/start/getting-started)
Both will point to the same page.
:::
The difference between URL format and file path format is that Rspress will automatically add the `.html` suffix based on the [`cleanUrls`](/api/config/config-basic#routecleanurls) configuration, so you don't need to consider the `.html` suffix in links - both with and without it will have consistent rendering results.
## External links
External links that are not in this docsite will automatically add `target="_blank" rel="noreferrer"`:
- [Rspack Documentation](https://rspack.rs/)
- [Rsbuild Documentation](https://rsbuild.rs/)
## Assets links
Links to static resources in the documentation site will be kept as is:
- Static assets in public folder - [/og-image.png](/og-image.png)
- Generated by @rspress/plugin-llms - [/llms-full.txt](/llms-full.txt)
:::tip
You need to exclude these links from [dead link checking](#dead-links-checking).
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
link: {
checkDeadLinks: {
excludes: ['/og-image.png', '/llms-full.txt'],
},
},
},
});
```
:::
## Link definition syntax
Rspress also supports markdown's alternative `definition` syntax for links, which can simplify link writing when there are many links.
```mdx
Rspress supports [relative file paths] and [absolute file paths].
[relative file paths]: ../start/getting-started.mdx
[absolute file paths]: /guide/start/getting-started.mdx
```
Rspress supports [relative file paths] and [absolute file paths].
[relative file paths]: ../start/getting-started.mdx
[absolute file paths]: /guide/start/getting-started.mdx
## Anchor links
Rspress supports adding anchor navigation in links, using the `#` symbol to specify jumping to a specific position on the page.
```mdx
[Jump to #File Path Format](#file-path-format)
[Jump to Getting Started#1-Initialize Project](../start/getting-started.mdx#1-initialize-project)
```
[Jump to #file-path-format](#file-path-format)
[Jump to Getting Started#1-initialize-the-project](../start/getting-started.mdx#1-initialize-the-project)
## Dead links checking
During the maintenance of documentation sites, broken links often occur. Rspress provides a dead link checking feature to specifically address this troublesome maintenance issue.
Configure through [markdown.link.checkDeadLinks](/api/config/config-build#markdownlinkcheckdeadlinks) to automatically check for invalid links.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
link: {
checkDeadLinks: true,
},
},
});
```
---
url: /guide/use-mdx/components.md
---
# MDX and React components
## Componentization
In MDX, all `.mdx` files are compiled into React components, which means they can be used as React components and can freely use React components. For example:
import { Tabs, Tab } from '@theme';
import { Border } from './_Border';
```mdx
import TsxComponent from './_tsx-component';
Testing the use of MDX fragments and React components.
This is **mdx fragment**.
```
```mdx file="./_mdx-fragment.mdx"
```
```tsx file="./_tsx-component.tsx"
```
It will be rendered as:
import MdxFragment from './_mdx-fragment.mdx';
import TsxComponent from './_tsx-component';
Testing the use of MDX fragments and React components.
This is **mdx fragment**.
You can use [built-in components](/guide/default-theme/components) provided by Rspress or install some React component libraries to enrich your documentation in `.mdx` files.
## Routing convention
In the [docs directory](/api/config/config-basic#root), MDX fragments or React components need to be excluded from routing through the [route.exclude](/api/config/config-basic#routeexclude) configuration. For convenience, we agree that files starting with "\_" will be excluded by default via [route.excludeConvention](/api/config/config-basic#routeexcludeconvention).
You can also place components in adjacent directories outside the docs directory, for example:
```mdx
import ButtonFragment from './_button.mdx';
import Button from '../../components/button';
```
```mdx file="./_button.mdx"
```
```tsx
const Button = () => ;
export default Button;
```
It will be rendered as:
import Button from './_button.mdx';
## Escape Hatch: writing document content using tsx or html
```tsx file="./_escape-hatch.tsx" title="_escape-hatch.tsx"
```
import EscapeHatch from './_escape-hatch';
It will be rendered as:
:::warning
tsx and html syntax can make it difficult to extract static information, such as local search indexes.
It is more recommended to use `.mdx` files to write document content and use `.tsx` files to write interactive dynamic content.
:::
---
url: /guide/use-mdx/container.md
---
# Container
Containers are a great way to mark important information and provide hints to users.
:::tip
Rspress provides two styles of syntax, [`:::` syntax](#three-colon-syntax) and [GitHub Markdown Alerts syntax](#github-markdown-alerts-syntax).
:::
## `:::` Syntax \{#three-colon-syntax}
You can use the `:::` syntax to create custom containers and support custom titles. For example:
import { Tabs, Tab } from '@theme';
:::note
This is a `block` of type `note`
:::
:::tip
This is a `block` of type `tip`
:::
:::info
This is a `block` of type `info`
:::
:::warning
This is a `block` of type `warning`
:::
:::danger
This is a `block` of type `danger`
:::
:::details
This is a `block` of type `details`
:::
:::tip Custom Title
This is a `block` of `Custom Title`
:::
:::tip\{title="Custom Title"}
This is a `block` of `Custom Title`
:::
```markdown
:::note
This is a `block` of type `note`
:::
:::tip
This is a `block` of type `tip`
:::
:::info
This is a `block` of type `info`
:::
:::warning
This is a `block` of type `warning`
:::
:::danger
This is a `block` of type `danger`
:::
:::details
This is a `block` of type `details`
:::
:::tip Custom Title
This is a `block` of `Custom Title`
:::
:::tip{title="Custom Title"}
This is a `block` of `Custom Title`
:::
```
:::warning
We recommend using the syntax `:::tip Custom Title` directly.
When using the `:::` syntax in `.mdx` files and customizing headings with curly braces syntax, be aware of escaping.
```mdx
:::tip\{title="Custom Title"}
This is a `block` of `Custom Title`
:::
```
:::
## GitHub Markdown alerts syntax \{#github-markdown-alerts-syntax}
You can use [GitHub Markdown Alerts Syntax](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) to create custom containers.
> [!NOTE]
> This is a `block` of type `note`
> [!TIP]
> This is a `block` of type `tip`
> [!INFO]
> This is a `block` of type `info`
> [!WARNING]
> This is a `block` of type `warning`
> [!DANGER]
> This is a `block` of type `danger`
> [!DETAILS]
> This is a `block` of type `details`
```markdown
> [!NOTE]
> This is a `block` of type `note`
> [!TIP]
> This is a `block` of type `tip`
> [!INFO]
> This is a `block` of type `info`
> [!WARNING]
> This is a `block` of type `warning`
> [!DANGER]
> This is a `block` of type `danger`
> [!DETAILS]
> This is a `block` of type `details`
```
---
url: /guide/default-theme/navbar.md
---
# Navbar
The navbar is very important to a website. It allows users to quickly jump between different pages of the website, and also allows users to quickly find some important information of the website.
## Custom navigation menu
You can add a custom navigation menu in `themeConfig.nav`, configured as an array, as follows:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
nav: [],
},
});
```
The nav bar is configured as an array, and each item in the array is a `NavItem` object, which has the following types:
```ts
export type NavItem = NavItemWithLink | NavItemWithChildren;
```
That is, each navbar element ( `NavItem` ) can be a link ( `NavItemWithLink` ), or a navbar group containing child elements ( `NavItemWithChildren` ).
### NavItemWithLink
```ts
export interface NavItemWithLink {
text: string;
link: string;
activeMatch?: string;
position?: 'left' | 'right';
}
```
The meanings of the attributes are as follows:
- `text` - Navbar text
- `link` - Navbar link
- `activeMatch` - Activation rule for navbar links
- `position` - Navbar menu item position
Attribute details:
`activeMatch` is used to match the current route, when the route matches the `activeMatch` rule, the nav item will be highlighted.
> By default, `activeMatch` is the `link` attribute of NavItem.
`position` is used to configure independent positioning of top menu items, with the following options available:
- `left` placed in the left menu bar at the top of the menu item;
- `right` placed in the right menu bar at the top of the menu item.
> If the `position` is not configured, it will be placed on the right menu bar by default, which is equivalent to configuring `right` .
### NavItemWithChildren
```ts
export interface NavItemWithChildren {
text: string;
items: NavItem[];
position?: 'left' | 'right';
}
```
The meanings of the attributes are as follows:
- `text` - Navbar text
- `items` - Sub navbar elements
- `position` - Navbar menu item position with child navbar elements
### Example
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
nav: [
{
text: 'Home',
link: '/',
position: 'left',
},
{
text: 'Links',
items: [
{
text: 'GitHub',
link: 'http://github.com/',
},
{
text: 'X',
link: 'http://x.com/',
},
],
position: 'left',
},
],
},
});
```
## Light/Dark Mode
By default, the navbar will have a toggle button for `Light/Dark` mode, you can disable it with the following config:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
darkMode: false,
},
});
```
## Related links
Social Links to the Site. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
socialLinks: [
{
icon: 'github',
mode: 'link',
content: 'https://github.com/web-infra-dev/modern.js',
},
],
},
});
```
For more configurations, please refer to [links](/api/config/config-theme#sociallinks).
---
url: /guide/default-theme/home-page.md
---
# Home page
You can define the content of the Home page through frontmatter, see [FrontMatter Config](/api/config/config-frontmatter.html#hero) for detailed types. Here is a simple example:
```yaml
---
pageType: home
hero:
name: Rspress
text: A documentation solution
tagline: A modern documentation development technology stack
actions:
- theme: brand
text: Introduction
link: /en/guide/introduction
- theme: alt
text: Quick Start
link: /en/guide/getting-started
features:
- title: 'MDX Support'
details: MDX is a powerful way to write content. You can use React components in Markdown.
icon: 📦
- title: 'Feature Rich'
details: Out of box support for i18n, full-text search etc.
icon: 🎨
- title: 'Customizable'
details: You can customize the theme ui and the build process.
icon: 🚀
---
```
---
url: /guide/default-theme/doc-page.md
---
# Doc page
## Page type
You can specify the pageType in the `frontmatter` metadata to use different layouts in the page. By default, the pageType of the document is `doc`, so the `sidebar` on the left and the `outline ` on the right will appear by default. If you don't need these, you can set pageType to `custom`:
```yaml
---
pageType: custom
---
```
## Sidebar
In `rspress.config.ts`, you can configure the content of the sidebar, for details, please refer to [Sidebar Config](/api/config/config-theme#sidebar).
## Outline title
With the `outlineTitle` config, you can set the title of the outline bar.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
themeConfig: {
outlineTitle: 'ON THIS PAGE',
},
});
```
## Previous/Next page text
With the `prevPageText` and `nextPageText` config, you can set the previous/next page text.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
prevPageText: 'Prev Page',
nextPageText: 'Next Page',
},
});
```
---
url: /guide/default-theme/overview-page.md
---
# Overview page
## Effect
Rspress has a built-in preview page, the effect is as follows:
## How to use
Generating the preview page requires the following two steps:
### 1. Create a new directory and configure frontmatter
For example, create the following directories and files
```txt
├── docs
│ ├── index.md
│ ├── api
│ │ ├── index.md
│ │ ├── theme
│ │ │ ├── component.mdx
│ │ │ ├── utils.mdx
// ...
```
We add the following to `api/index.md`:
```md
---
overview: true
---
```
::: note
The title of the overview page can be configured through frontmatter. The default value is `Overview`. After `title` is configured in frontmatter, there is no need to write an H1 title in the markdown content.
```md
---
overview: true
title: Overview
---
This is an Overview page of our website.
```
:::
### 2. Configuring `_meta.json`
The content structure of the overview page will be automatically generated according to `_meta.json` and the corresponding h1, h2 titles of the article. For example, the configuration of `api/_meta.json` is as follows:
```json
[
{
"type": "file",
"name": "index",
"label": "API Overview"
},
{
"type": "dir",
"name": "theme",
"label": "Theme"
}
]
```
At the same time, the file `api/theme/_meta.json` has the following content:
```json
["component", "utils"]
```
> The detailed configuration usage of `_meta.json` can be referred to [Auto Nav/Sidebar](/guide/basic/auto-nav-sidebar).
In the above configuration, the final preview page will generate a group called `Theme`, which contains the h1, h2 titles of two articles: `component.md(x)` and `utils.md(x)`. Of course, you can also refer to the config of the `Theme` group to add more groups.
If you want to control the headers displayed in the overview page, you can configure it through `overviewHeaders` config in `_meta.json`, which defaults to `[2]` and you can also configure FrontMatter with `overviewHeaders: [2]` in exact file.
If you want to generate a sub-preview page under `theme`, there are two ways:
1. Create a new file `theme.md` with the same name in the parent directory of `theme` and configure the frontmatter of `overview: true`.
```txt
├── docs
│ ├── index.md
│ ├── api
│ │ ├── index.md
│ │ ├── theme.md
│ │ ├── theme
│ │ │ ├── component.mdx
│ │ │ ├── utils.mdx
//...
```
2. Create a new `index.md` in the `theme` directory and configure the frontmatter of `overview: true`.
```txt
├── docs
│ ├── index.md
│ ├── api
│ │ ├── index.md
│ │ ├── theme
│ │ │ ├── index.md
│ │ │ ├── component.mdx
│ │ │ ├── utils.mdx
//...
```
Then configure `theme/_meta.json` as follows:
```json
[
{
"type": "file",
"name": "index",
"label": "Overview"
}
]
```
---
url: /guide/default-theme/i18n.md
---
# Internationalization
To achieve document internationalization in Rspress, you need to do the following:
1. Defines I18n text data.
2. Configure `locales` and `themeConfig.locales`。
3. Configure the default language.
4. Create documents in different language version.
5. Configure sidebar and navbar.
6. Use `useI18n` in custom components.
## Defines I18n text data
Create a new `i18n.json` in the current workspace, the directory structure is as follows:
```txt
.
├── docs
├── i18n.json
├── package.json
├── tsconfig.json
└── rspress.config.ts
```
In this JSON file, you can define the text needed for internationalization, the type definition is as follows:
```ts
export interface I18n {
// key: text id
[key: string]: {
// key: language
[key: string]: string;
};
}
```
For example:
```json title="i18n.json"
{
"gettingStarted": {
"en": "Getting Started",
"zh": "开始"
},
"features": {
"en": "Features",
"zh": "特性"
},
"guide": {
"en": "Guide",
"zh": "指南"
}
}
```
These text data are used in both **config file** and **custom components**, which will be introduced in detail later.
## Configure `locales`
In `rspress.config.ts`, you can configure `locales` data in two places:
- `locales`, used to configure the `lang`, `title`, `description` and other information of the site, mainly around the information of the site itself.
- `themeConfig.locales`, used to configure the theme's `lang`, `outline title`, `previous page/next page text` and other information, mainly for theme-related config.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
locales: [
{
lang: 'en',
// The label in nav bar to switch language
label: 'English',
title: 'Rspress',
description: 'Static Site Generator',
},
{
lang: 'zh',
label: '简体中文',
title: 'Rspress',
description: '静态网站生成器',
},
],
themeConfig: {
locales: [
{
lang: 'en',
outlineTitle: 'ON THIS Page',
},
{
lang: 'zh',
outlineTitle: '大纲',
},
],
},
});
```
:::tip Note
In the default theme, `themeConfig.locales` also contains all the fields in `locales`, the former takes precedence.
:::
For other international theme parameters, please refer to [API type](/api/config/config-theme#locales).
## Configure the default language
After configure `locales` data, you need configure the default language of the document via [lang](/api/config/config-basic#lang), as shown in the following example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
lang: 'en',
});
```
This is important because **for routes in the default language, Rspress will remove the language prefix**, such as `/en/guide/getting-started` will be converted to `/guide/getting-started`.
## Create documents in different language
After the above configuration, we can start to create documents in different language versions. It is very simple. We only need to create the following structure in the document root directory:
```txt
docs
├── en
│ ├── api
│ │ └── index.md
│ └── guide
│ └── getting-started.md
│ └── features.md
└── zh
├── api
│ └── index.md
└── guide
└── getting-started.md
└── features.md
```
As you can see, we put documents in different languages in the `en` and `zh` directories under the `docs` directory, so that we can easily distinguish documents in different languages.
## Configuring \_meta.json
Through the \_meta.json file, we can configure the content of the nav bar and sidebar. For details, please refer to [Auto Nav/Sidebar](/guide/basic/auto-nav-sidebar).
### Navigation bar level
In the \_meta.json configuration at the navigation bar level, you can specify `text` as an i18n key, for example:
```json title="_meta.json"
[
{
"text": "guide",
"link": "/guide/start/getting-started",
"activeMatch": "/guide/"
}
]
```
Here, `text` is `guide`, this value will be automatically translated into `指南` or `Guide`, depending on the current language.
### Sidebar level
In the \_meta.json configuration at the sidebar level, you can specify `label` as an i18n key, for example:
```json title="_meta.json"
[
{
"type": "dir",
"name": "start",
"label": "gettingStarted"
}
]
```
Here, `label` is `gettingStarted`, this value will be automatically translated into `开始` or `Getting Started`, depending on the current language.
## Use `useI18n` in custom components
In the process of MDX development or custom theme development, you may write some custom components, which also need to use international text, so how to get it?
Rspress provides `useI18n` this hook to get the internationalized text, the usage is as follows:
```tsx
import { useI18n } from '@rspress/core/runtime';
const MyComponent = () => {
const t = useI18n();
return
{t('gettingStarted')}
;
};
```
For better type hinting, you can configure `paths` in tsconfig.json:
```json
{
"compilerOptions": {
"paths": {
"i18n": ["./i18n.json"]
}
}
}
```
Then use it like this in the component:
```tsx
import { useI18n } from '@rspress/core/runtime';
const MyComponent = () => {
const t = useI18n();
return
{t('gettingStarted')}
;
};
```
This way you get type hints for all literal keys defined in `i18n.json`.
---
url: /guide/default-theme/multi-version.md
---
# Multi version
Rspress's default theme supports multi-version document management. Next, we will introduce how to access multi-version documents.
## `multiVersion` config
Configure the version list and default version through `multiVersion`, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
multiVersion: {
default: 'v1',
versions: ['v1', 'v2'],
},
});
```
Here, `default` is the default version, and `versions` is the version list.
## Adding multi-version documents
According to the version list you configured, add multi-version documents under the `docs` directory, for example:
```txt
docs
├── v1
│ ├── README.md
│ └── guide
│ └── README.md
└── v2
├── README.md
└── guide
└── README.md
```
In Rspress's conventional routing, for the default version, the version path prefix will be automatically omitted. For example, `v1/README.md` will be rendered as the `/README` route, while `v2/README.md` will be rendered as the `/v2/README` route.
:::tip Tip
For links in the document, you do not need to manually add the version prefix. Rspress will automatically add the corresponding version prefix according to the version of the current document. For example, the link `/guide/README` in `v2/README.md` will be rendered as `/v2/guide/README`.
:::
## Get the current version in components
In components, you can get the current version through `useVersion`, for example:
```tsx
import { useVersion } from '@rspress/core/runtime';
export default () => {
const version = useVersion();
return
Current version: {version}
;
};
```
## Limit search to current version only
You can configure `search.versioned` to only search through the current version's documents.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
multiVersion: {
default: 'v1',
versions: ['v1', 'v2'],
},
search: {
versioned: true,
},
});
```
---
url: /guide/default-theme/components.md
---
# Built-in components
:::info Note
In order to make it easier for you to use these components, the `rspress/theme` package has been aliased inside Rspress, so you can directly use `@theme` to import these components.
:::
## Badge
The Badge component is used to display a badge. For example:
```tsx title="index.mdx"
import { Badge } from '@theme';
function App() {
// Using text prop
return ;
// Using custom children
return (
Rspress
);
}
```
The effect is as follows:
import { Badge } from '@theme';
Custom children:
import SearchSvg from '@theme-assets/github';
RspressGithub
Inlined with text
##### H5
#### H4
### H3
The types of props included are as follows:
```ts
interface BadgeProps {
/**
* The content to display inside the badge. Can be a string or React nodes.
*/
children?: React.ReactNode;
/**
* The type of badge, which determines its color and style.
* @default 'tip'
*/
type?: 'tip' | 'info' | 'warning' | 'danger';
/**
* The text content to display inside the badge (for backwards compatibility).
*/
text?: string;
/**
* Whether to display the badge with an outline style.
* @default false
*/
outline?: boolean;
}
```
## Head
It is generally used to set custom head content in documents (based on [unhead](https://www.npmjs.com/package/unhead)). The usage is as follows:
```tsx title="index.tsx"
// Below is a custom component, you can import it into your document
import { Head } from '@rspress/core/runtime';
function App() {
return (
);
}
```
## HomeFeature
Feature component in Hero page, look [the effect in this website](/).
```tsx
import { HomeFeature } from '@rspress/core/theme';
interface Feature {
title: string;
details: string;
icon: string;
// only support [3, 4, 6]
span?: number;
link?: string;
}
export type Features = Feature[];
```
## HomeHero
Hero component in Hero page.
```tsx
import { HomeHero } from '@rspress/core/theme';
interface Hero {
name: string;
text: string;
tagline: string;
image?: {
src: string | { dark: string; light: string };
alt: string;
};
actions: {
text: string;
link: string;
theme: 'brand' | 'alt';
}[];
}
```
## LastUpdated
The LastUpdated component is used to display the last update time of the current page. For example:
```tsx title="index.mdx"
import { LastUpdated } from '@theme';
function App() {
return ;
}
```
:::tip
If `lastUpdated: true` is not configured in the default theme, you need to install and register the `@rspress/plugin-last-updated` plugin.
:::
## NoSSR
Used to skip the ssr for some components. For example:
```tsx
import { NoSSR } from '@rspress/core/runtime';
const Component = () => {
return (
The content here will only be rendered on the client side
);
};
```
## Overview
Overview component, look [the effect in this website](/api/)
```tsx
import { Overview } from '@rspress/core/theme';
interface GroupItem {
text?: string;
link?: string;
headers?: Header[];
}
interface Group {
name: string;
items: GroupItem[];
}
interface OverviewProps {
// content before data rendering
content?: React.ReactNode;
// data
groups?: Group[];
// default title
defaultGroupTitle?: string;
// headers displayed in the overview page of the file
overviewHeaders?: number[];
}
```
## PackageManagerTabs
The PackageManagerTabs component is used to display commands for different package managers in the documentation. The usage is as follows:
```tsx title="index.mdx"
import { PackageManagerTabs } from '@theme';
function App() {
return ;
}
```
The effect is as follows:
import { PackageManagerTabs } from '@theme';
The types of props included are as follows:
```ts
type PackageManagerTabProps = (
| {
command: string;
/**
* If true, the command will be interpreted as a shell command and prefixed with npx for npm,
* or the package manager binary for others.
*/
exec?: boolean;
}
| {
command: {
// Used to set commands for different package managers
npm?: string;
yarn?: string;
pnpm?: string;
bun?: string;
};
exec?: never;
}
) &
// Used to set additional tabs
{
additionalTabs?: {
// Used to set additional package managers
tool: string;
// Used to set the icon of the additional package manager
icon?: ReactNode;
}[];
};
```
When `command` is set to a string, it will default to displaying three tabs: npm, yarn, pnpm and bun, and the component will automatically add the corresponding package manager command before the command. If you need to display additional tabs, you can achieve this through `additionalTabs`.
For the `string` variant of the `command` prop, an optional `exec` prop can be used for presenting binary execution usage (by changing the NPM tab's command prefix to `npx`).
:::tip
In the install command, special processing has been done for yarn, pnpm and bun. If your command is `install some-packages`, the install will be automatically replaced with add in the yarn/pnpm/bun tab.
:::
## PrevNextPage
The PrevNextPage component is used to display the previous and next pages of the current page. For example:
```tsx title="index.mdx"
import { PrevNextPage } from '@theme';
function App() {
return (
);
}
```
The types of props included are as follows:
```ts
interface PrevNextPageProps {
// Set the link to the previous page or the next page through type
type: 'prev' | 'next';
// Used to set the text of the previous page or the next page
text: string;
// Used to set the link to the previous page or the next page
href: string;
}
```
## SourceCode
The SourceCode component is used to jump to the source code. For example:
```tsx title="index.mdx"
import { SourceCode } from '@theme';
function App() {
return (
);
}
```
The effect is as follows:
import { SourceCode } from '@theme';
The types of props included are as follows:
```ts
interface SourceCodeProps {
// Used to set the link to the source code
href: string;
// Used to set source platform
platform?: 'github' | 'gitlab';
}
```
## Steps
The Steps component is used to turn your content into a visual representation of steps.
```tsx title="index.mdx"
import { Steps } from '@theme';
function App() {
return (
### Step 1
Body for Step 1.
### Step 2
> Body for Step 2.
);
}
```
The effect is as follows:
import { Steps } from '@theme';
### Step 1
Body for Step 1.
### Step 2
> Body for Step 2.
## Tab/Tabs
You can use the `Tab` and `Tabs` component in the document to achieve the effect of tab switching. For example:
```mdx title="index.mdx"
import { Tab, Tabs } from '@rspress/core/theme';
Tab 1 contentTab 2 content
```
import { Tab, Tabs } from '@theme';
Tab 1 contentTab 2 content
### Code blocks
Using `Tabs` component to switch multiple code blocks.
````mdx title="index.mdx"
import { Tab, Tabs } from '@rspress/core/theme';
```tsx title="src/index.mjs"
import foo from 'foo';
import bar from 'bar';
```
```tsx title="src/index.cjs"
const foo = require('foo');
const bar = require('bar');
```
````
```tsx title="src/index.mjs"
import foo from 'foo';
import bar from 'bar';
```
```tsx title="src/index.cjs"
const foo = require('foo');
const bar = require('bar');
```
### Props
The props type of the Tabs component is as follows:
```ts
interface TabsProps {
children: React.ReactNode;
defaultValue?: string;
groupId?: string;
tabPosition?: 'left' | 'center';
}
```
- `defaultValue` is used to set the tab item selected by default. This value will be compared with the value field of the Tab component props, and if they are equal, the tab will be selected.
- `groupId` is used to sync the selected tab item between multiple Tabs components.The groups with the same groupId will be synchronized.
- `tabPosition` is used to set the position of the tab list, it has two values: `left` and `center`, the default is `left`.
The props types of the Tab component are as follows:
```ts
interface TabProps {
label: string;
// Used to identify the current tab, if not passed, the default label will be used
value?: string;
children: React.ReactNode;
}
```
The `value` field is used to identify the current tab, if not passed, the default label will be used.
## Table of contents
Render TOC of current page
```tsx title="index.mdx"
import { Toc } from '@theme';
function App() {
return ;
}
```
import { Toc } from '@theme';
## CodeBlockRuntime
Render code block in runtime
```tsx title="index.mdx"
import { CodeBlockRuntime } from '@theme';
function App() {
return (
);
}
```
import { CodeBlockRuntime } from '@theme';
---
url: /guide/advanced/extend-build.md
---
# Build extension
## Rsbuild
Rspress builds documents based on [Rsbuild](https://github.com/web-infra-dev/rsbuild).
### Configure Rsbuild
Rsbuild provides a rich set of build configurations. You can customize these configurations through [builderConfig](/api/config/config-build.html#builderconfig). For example, change the output directory to `doc_dist`:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
builderConfig: {
output: {
distPath: {
root: 'doc_dist',
},
},
},
});
```
Rspress also provides the [builderConfig.plugins](/api/config/config-build#builderconfigplugins) config to register Rsbuild plugins. You can leverage Rsbuild's extensive plugin ecosystem to enhance and extend your build capabilities.
For example, add Google analytics through [rsbuild-plugin-google-analytics](https://github.com/rspack-contrib/rsbuild-plugin-google-analytics):
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginGoogleAnalytics } from 'rsbuild-plugin-google-analytics';
export default defineConfig({
builderConfig: {
plugins: [
pluginGoogleAnalytics({
// replace this with your Google tag ID
id: 'G-xxxxxxxxxx',
}),
],
},
});
```
:::tip
You can learn more about the configuration options through [Rsbuild - Config](https://rsbuild.rs/config/) documentation.
:::
### Configure Rspack
You can configure Rspack through the [tools.rspack](https://rsbuild.rs/config/tools/rspack) option provided by Rsbuild:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
builderConfig: {
tools: {
rspack(options) {
// modify the rspack configuration
},
},
},
});
```
## MDX compilation
The compilation of MDX in Rspress is based on [unified](https://github.com/unifiedjs/unified), and you can add related compilation plugins through `markdown` configuration. for example
:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
// It's necessary to use JS version compiler
mdxRs: false,
remarkPlugins: [
[
require('remark-autolink-headings'),
{
behavior: 'wrap',
},
],
],
rehypePlugins: [require('rehype-slug')],
},
});
```
:::warning
Only the JS version of the MDX compiler supports compilation plugins.
:::
---
url: /guide/advanced/custom-search.md
---
# Customize search functions
In some scenarios, we need to customize the search function, such as:
- Processing keywords in the search process, such as removing sensitive words.
- Filtering the default full-text search results.
- Reporting the search keywords.
- Customizing the search data source, such as searching from the database.
- Rendering the custom search data source.
- ......
Faced with these flexible custom requirements, we provide corresponding interfaces to extend the search components of the default theme, making it easy for you to customize the search function.
## Understanding `searchHooks`
In the Rspress config, we provide a `search.searchHooks` config item for configuring the hook functions of the search components, as follows:
```js
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
search: {
searchHooks: path.join(__dirname, './search.tsx'),
},
});
```
The value of the `search.searchHooks` config item is a file path. This file will export the corresponding hook logic, such as `onSearch`, so that you can customize the capabilities of the search at run time. We can call this file a **`searchHooks` module**.
## Hook functions in searchHooks
Next, let us introduce the hook functions in searchHooks, namely `beforeSearch`, `onSearch`, `afterRender` and `render`.
:::tip
In the searchHooks module, you only need to export the hook functions you need, instead of necessarily exporting all the hook functions.
:::
### beforeSearch
The `beforeSearch` hook function will be executed before the search starts, you can use it to process the search keywords, such as removing sensitive words, or reporting the search keywords.
> This hook supports asynchronous operations.
Here is an example of usage:
```ts
import type { BeforeSearch } from '@rspress/core/theme';
const beforeSearch: BeforeSearch = (query: string) => {
// Some operations before search can be done here
console.log('beforeSearch');
// Return the processed query
return query.replace(' ', '');
};
export { beforeSearch };
```
### onSearch
The `onSearch` hook function will be executed after the default full-text search logic is finished. You can use this hook function to filter or report the search results, or you can add a custom search data source in this hook function.
> This hook supports asynchronous operations.
Here is an example of how to use it:
```ts
import type { OnSearch } from '@rspress/core/theme';
import { RenderType } from '@rspress/core/theme';
const onSearch: OnSearch = async (query, defaultSearchResult) => {
// Can request data based on query
console.log(query);
// The results of the default search source, which is an array
console.log(defaultSearchResult);
// const customResult = await searchQuery(query);
// Can directly operate the default search results.
defaultSearchResult.pop();
// The return value is an array, each item in the array is a search source result, and they will be added to the search result
return [
{
group: 'Custom',
result: {
list: [
{
title: 'Search Result 1',
path: '/search1',
},
{
title: 'Search Result 2',
path: '/search2',
},
],
},
renderType: RenderType.Custom,
},
];
};
export { onSearch };
```
Note that the return value of the `onSearch` hook function is an array, each item in the array is a search source result, and each item has the following structure:
```ts
{
group: string; // The group name of the search result, which will be displayed in the search results.
result: unknown;
renderType: RenderType; // The type of the search result, which can be `RenderType.Default` or `RenderType.Custom`. `RenderType.custom` by default.
}
```
The `result` is the search result, you can customize its internal structure. The `renderType` is the type of the search result, which can be `RenderType.Default` or `RenderType.Custom`. If it is `RenderType.Default`, the default search result rendering logic will be used; if it is `RenderType.Custom`, the `render` function will be used to render the search result.
### afterSearch
The `afterSearch` hook function will be executed after the search result is rendered. You can get the final search keywords and search results in this hook.
> This hook supports asynchronous operations.
Here is an example of usage:
```ts
import type { AfterSearch } from '@rspress/core/theme';
const afterSearch: AfterSearch = async (query, searchResult) => {
// Search keyword
console.log(query);
// Search result
console.log(searchResult);
};
export { afterSearch };
```
### render
The `render` function will render the custom search source data in your `onSearch` hook. Therefore, it generally needs to be used together with `onSearch`. Here's how to use it:
```tsx
import type { RenderSearchFunction } from '@rspress/core/theme';
// The above OnSearch hook implementation is skipped
interface ResultData {
list: {
title: string;
path: string;
}[];
}
// The render function for each search source
const render: RenderSearchFunction = (item) => {
return (
);
};
export { onSearch, render };
```
The result is as follows:

---
url: /guide/basic/frontmatter.md
---
# Frontmatter
You can add front matter at the beginning of your Markdown file, which is a special part that uses [YAML](https://yaml.org/) format to define metadata, and is included in the file's top three dashes `---`.
For example, use [title](/api/config/config-frontmatter#title) to specify the title of the page:
```yaml
---
title: Hello world
---
```
You can also access properties defined in front matter in the body, for example:
```markdown
---
title: Hello world
---
# {frontmatter.title}
```
The previously defined properties will be passed to the component as `frontmatter` properties. So the final output will be:
```html
Hello world
```
:::tip
See [Front matter config](/api/config/config-frontmatter) for available front matter configurations.
:::
---
url: /plugin/system/introduction.md
---
# Introduction
The plugin system is a crucial part of Rspress, which allows you to easily extend the abilities of Rspress during the process of building a site. So, what ability can you extend with plugins? Let's take a look at the overall architecture of Rspress first.
The overall architecture of Rspress is shown in the figure below:

Rspress is divided into two parts: **Node Side** and **Browser Runtime**. Through the plugin system, you can easily extend the abilities of these two parts. Specifically, you can extend the ability to:
- [**Markdown/MDX compilation**](/plugin/system/plugin-api#markdown)。You can add [`remark`](https://github.com/remarkjs/remark)/[`rehype`](https://github.com/rehypejs/rehype) plugins to extend the compilation ability of Markdown/MDX.
- [**Add custom page**](/plugin/system/plugin-api#addpages). On the basis of Rspress's conventional routing, you can also add new routes through plugins, such as adding a `/blog` route to display a list of blogs, and the content is defined by yourself.
- [**Custom build tool behavior**](/plugin/system/plugin-api#builderconfig).In Rspress plugin, you can customize the config of the underlying build tool [Rsbuild](https://rsbuild.rs), and you can also add some Rspack or Rsbuild plugins.
- [**Extend page metadata**](/plugin/system/plugin-api#extendpagedata). For each page, some metadata will be calculated inside Rspress, such as `title`, `description`, etc. You can extend the calculation logic of these metadata through plugins, and pass [usePageData](/api/client-api/api-runtime.html#usepagedata) hook access.
- Insert some [**custom logic**](/plugin/system/plugin-api#beforebuild/afterbuild) before and after the build process. Such as closing some event listeners after the build process ends.
- [**Add global components**](/plugin/system/plugin-api#globaluicomponents). Rspress internally uses React for rendering. You can flexibly extend the runtime page by defining global React components, such as `adding a global BackToTop (return to top) component`, `adding a global side effect logic`.
---
url: /plugin/system/write-a-plugin.md
---
# Write a plugin
Let's inject a global component as an example to see how to define and use plugins.
### 1. Define a plugin
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginExample(slug: string): RspressPlugin {
// Component path, you need to implement the content of the component yourself
const componentPath = path.join(__dirname, 'Example.tsx');
return {
name: 'plugin-example',
// Path to global components
globalUIComponents: [componentPath],
// Global variable definitions for build phase
builderConfig: {
source: {
define: {
'process.env.SLUG': JSON.stringify(slug),
},
},
},
};
}
```
```tsx title="Example.tsx"
import React from 'react';
const Example = () => {
console.log(process.env.SLUG);
return
Example
;
};
export default Example;
```
A plugin is generally a function that receives some plugin params (optional) and returns an object that contains the name of the plugin and other config.
In the above example, we define a plugin named `plugin-example`, which will define a global environment variable `process.env.SLUG` during the build phase, and inject a global component `Example.tsx` in the document.
### 2. Use a plugin
Register plugins via `plugins` in `rspress.config.ts`:
```tsx title="rspress.config.ts"
import { pluginExample } from './plugin';
export default {
plugins: [pluginExample('test')],
};
```
Then the `Example` component will be injected into the page and we can access the `process.env.SLUG` variable in the component.
---
url: /plugin/system/plugin-api.md
---
# Plugin API
In the previous section, we introduced the basic structure of the plugin. In this section, we will introduce the API of the plugin to help you understand the abilities of the plugin in more detail.
### globalStyles
- **Type**:`string`
It is used to add a global style, and the absolute path of a style file is passed in, and the usage is as follows:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
import path from 'path';
export function pluginForDoc(): RspressPlugin {
// style path
const stylePath = path.join(__dirname, 'some-style.css');
return {
// plugin name
name: 'plugin-name',
globalStyles: path.join(__dirname, 'global.css'),
};
}
```
For example, if you want to modify the theme color, you can do so by adding a global style:
```css title="global.css"
:root {
--rp-c-brand: #ffa500;
--rp-c-brand-dark: #ffa500;
--rp-c-brand-darker: #c26c1d;
--rp-c-brand-light: #f2a65a;
--rp-c-brand-lighter: #f2a65a;
}
```
### globalUIComponents
- **Type**:`(string | [string, object])[]`
It is used to add global components, passing in an array, each item in the array is the absolute path of a component, the usage is as follows:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
// component path
const componentPath = path.join(__dirname, 'foo.tsx');
return {
// plugin name
name: 'plugin-comp',
// Path to global components
globalUIComponents: [componentPath],
};
}
```
The item of `globalUIComponents` can be a string, which is the path of the component file, or an array, the first item is the path of the component file, and the second item is the component props, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
// component path
const componentPath = path.join(__dirname, 'foo.tsx');
return {
// plugin name
name: 'plugin-comp',
globalUIComponents: [
[
path.join(__dirname, 'components', 'MyComponent.tsx'),
{
foo: 'bar',
},
],
],
};
}
```
When you register global components, Rspress will automatically render these React components in the theme without manually importing and using them.
Through global components, you can complete many custom functions, such as:
```tsx title="compUi.tsx"
import React from 'react';
// Need a default export
// The props comes from your config
export default function PluginUI(props?: { foo: string }) {
return
This is a global layout component
;
}
```
In this way, the content of the component will be rendered in the theme page, such as adding **BackToTop** button.
In the meanwhile, you can also use the global component to register some side effects, such as:
```tsx title="compSideEffect.tsx"
import { useEffect } from 'react';
import { useLocation } from '@rspress/core/runtime';
// Need a default export
export default function PluginSideEffect() {
const { pathname } = useLocation();
useEffect(() => {
// Executed when the component renders for the first time
}, []);
useEffect(() => {
// Executed when the route changes
}, [pathname]);
return null;
}
```
This way, side effects of components are executed in the theme page. For example, some of the following scenarios require side effects:
- Redirect for certain page routes.
- Bind click event on the img tag of the page to implement the image zoom function.
- When the route changes, the PV data of different pages are reported.
- ......
### builderConfig
- **Type**:`RsbuildConfig`
Rspress uses [Rsbuild](https://github.com/web-infra-dev/rsbuild) as the build tool. Rsbuild can be configured through `builderConfig`. For specific configuration options, please refer to [Rsbuild(https://rsbuild.rs/config/).
> Of course, if you want to configure Rspack directly, you can also configure it through `builderConfig.tools.rspack`.
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(slug: string): RspressPlugin {
return {
name: 'plugin-name',
// Global variable definitions for build phase
builderConfig: {
source: {
define: {
SLUG: JSON.stringify(slug),
},
},
tools: {
rspack(options) {
// Modify rspack config
},
},
},
};
}
```
> See [Build Config](/api/config/config-build) for more details.
### config
- **Type**:`(config: DocConfig, utils: ConfigUtils) => DocConfig | Promise`
The type of `ConfigUtils` is as follows:
```ts
interface ConfigUtils {
addPlugin: (plugin: RspressPlugin) => void;
removePlugin: (pluginName: string) => void;
}
```
It is used to modify/extend the configuration of Rspress itself. For example, if you want to modify the title of the document, you can do it through `config`:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
// Plugin name
name: 'plugin-name',
// Extend the config of the Rspress itself
config(config) {
return {
...config,
title: 'New Document Title',
};
},
};
}
```
If it involves adding and removing a plugin, you need to implement it through `addPlugin` and `removePlugin`:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
// Plugin name
name: 'plugin-name',
// Extend the config of Rspress itself
config(config, utils) {
// Add a plugin
utils.addPlugin({
name: 'plugin-name',
// ... other config of the plugin
});
// Remove a plugin, pass in the name of the plugin
utils.removePlugin('plugin-name');
return config;
},
};
}
```
### beforeBuild/afterBuild
- **Type**:`(config: DocConfig, isProd: boolean) => void | Promise`
It is used to perform some operations before/after the document is built. The first parameter is the config of the document, and the second parameter is whether it is currently a production environment. The usage is as follows:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
name: 'plugin-name',
// Hook to execute before build
async beforeBuild(config, isProd) {
// Do something here
},
// Hook to execute after build
async afterBuild(config, isProd) {
// Do something here
},
};
}
```
:::tip
When the `beforeBuild` hook is executed, the `config` plugins of all plugins have been processed, so the config parameter already represents the final document configuration.
:::
### markdown
- **Type**:`{ remarkPlugins?: Plugin[]; rehypePlugins?: Plugin[] }`
It is used to extend the compilation ability of Markdown/MDX. If you want to add custom remark/rehype plugins or MDX globalComponents, you can use `markdown` options to achieve:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
name: 'plugin-name',
markdown: {
// Use js version compiler to support plugins
mdxRs: false,
remarkPlugins: [
// Add custom remark plugin
],
rehypePlugins: [
// Add custom rehype plugin
],
globalComponents: [
// Register global components for MDX
],
},
};
}
```
### extendPageData
- Type: `(pageData: PageData) => void | Promise`
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
name: 'plugin-name',
// Extend the page data
extendPageData(pageData, isProd) {
// You can add or modify properties on the pageData object
pageData.a = 1;
},
};
}
```
After extending the page data, you can access the page data through the `usePageData` hook in the theme.
```tsx
import { usePageData } from '@rspress/core/runtime';
export function MyComponent() {
const { page } = usePageData();
// page.a === 1
return
{page.a}
;
}
```
### addPages
- Type: `(config: UserConfig) => AdditionalPage[] | Promise`
The `config` parameter is the `doc` config of `rspress.config.ts`, and the `AdditionalPage` type is defined as follows:
```tsx
interface AdditionalPage {
routePath: string;
filepath?: string;
content?: string;
}
```
Used to add additional pages, you can return an array in the `addPages` function, each item in the array is a page config, you can specify the route of the page through `routePath`, through `filepath` or `content` to specify the content of the page. For example:
```tsx
import path from 'path';
import type { RspressPlugin } from '@rspress/core';
export function docPluginDemo(): RspressPlugin {
return {
name: 'add-pages',
addPages(config, isProd) {
return [
// Support the absolute path of the real file (filepath), which will read the content of md(x) in the disk
{
routePath: '/filepath-route',
filepath: path.join(__dirname, 'blog', 'index.md'),
},
// Support to directly pass in the content of md(x) through the content parameter
{
routePath: '/content-route',
content: '# Demo2',
},
];
},
};
}
```
`addPages` accepts two parameters, `config` is the config of the current document site, `isProd` indicates whether it is a production environment.
### routeGenerated
- **Type**:`(routeMeta: RouteMeta[]) => void | Promise`
In this hook, you can get all the route meta information. The structure of each route meta information is as follows
```ts
export interface RouteMeta {
// route path
routePath: string;
// file absolute path
absolutePath: string;
// The page name, as part of the chunk filename
pageName: string;
// language of current route
lang: string;
}
```
例子:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
// plugin name
name: 'plugin-routes',
// Hook to execute after route generated
async routeGenerated(routes, isProd) {
// Do something here
},
};
}
```
### addRuntimeModules
- **Type**: `(config: UserConfig, isProd: boolean) => Record | Promise>;`
Used to add additional runtime modules. For example, if you want to use some compile-time information in the document, you can achieve this through `addRuntimeModules`:
```tsx title="plugin.ts"
import type { RspressPlugin } from '@rspress/core';
export function pluginForDoc(): RspressPlugin {
return {
// Plugin name
name: 'plugin-name',
// Add additional runtime modules
async addRuntimeModules(config, isProd) {
const fetchSomeData = async () => {
// Mock asynchronous request
return { a: 1 };
};
const data = await fetchSomeData();
return {
'virtual-foo': `export default ${JSON.stringify(data)}`,
};
},
};
}
```
In this way, you can use the `virtual-foo` module in the runtime component:
```jsx
import myData from 'virtual-foo';
export function MyComponent() {
return
{myData.a}
;
}
```
:::tip TIP
This hook is executed after the `routeGenerated` hook.
:::
---
url: /plugin/official-plugins/overview.md
---
# Overview
## Official plugins
Official plugins include:
- [@rspress/plugin-llms](./llms): Generate [llms.txt](https://llmstxt.org/) related files for your Rspress site, allowing large language models to better understand your documentation site.
- [@rspress/plugin-medium-zoom](./medium-zoom): [medium-zoom](https://github.com/francoischalifour/medium-zoom) plugin, used to zoom in images.
- [@rspress/plugin-client-redirects](./client-redirects):Support client redirects.
- [@rspress/plugin-last-updated](./last-updated): Support for displaying the last update time of the article.
- [@rspress/plugin-typedoc](./typedoc): Integrate [TypeDoc](https://github.com/TypeStrong/typedoc), used to generate API documentation of TS module automatically.
- [@rspress/plugin-api-docgen](./api-docgen): Integrate [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript) and [documentation](https://github.com/documentationjs/documentation), used to generate api document description automatically.
- [@rspress/plugin-preview](./preview): Support preview of code blocks in Markdown/MDX.
- [@rspress/plugin-playground](./playground): Provide a real-time playground to preview the code blocks in Markdown/MDX files.
- [@rspress/plugin-rss](./rss):Generate RSS files with [feed](https://github.com/jpmonette/feed) for the document site.
---
url: /plugin/official-plugins/llms.md
---
# @rspress/plugin-llms
import { SourceCode } from '@rspress/core/theme';
Generate [llms.txt](https://llmstxt.org/) related files for your Rspress site, allowing large language models to better understand your documentation site.
## Installation
import { PackageManagerTabs } from '@theme';
## Usage
### 1. Install plugin
Add the following configuration to your configuration file:
```ts
// rspress.config.ts
import { defineConfig } from '@rspress/core';
import { pluginLlms } from '@rspress/plugin-llms';
export default defineConfig({
plugins: [pluginLlms()],
});
```
Then execute the `rspress build` command. While generating the output, the plugin will also generate `llms.txt`, `llms-full.txt`, and corresponding markdown files for each route in the output directory based on the navigation bar and sidebar.
### 2. UI display
If you want users reading your documentation site to better utilize large language models to read the documentation, you can add a copy Markdown button at the top of the page through [custom theme](/ui/custom-theme), with the same effect as this website.
Add a copy button to all pages, example:
```tsx title="theme/index.tsx"
import { getCustomMDXComponent as basicGetCustomMDXComponent } from '@rspress/core/theme';
import {
LlmsContainer,
LlmsCopyButton,
LlmsViewOptions,
} from '@rspress/plugin-llms/runtime';
function getCustomMDXComponent() {
const { h1: H1, ...mdxComponents } = basicGetCustomMDXComponent();
const MyH1 = ({ ...props }) => {
return (
<>
{/* [!code highlight:5] */}
{/* LlmsViewOptions component can be added as needed */}
>
);
};
return {
...mdxComponents,
h1: MyH1,
};
}
export { getCustomMDXComponent };
export * from '@rspress/core/theme';
```
Add a copy button to specific pages, example:
```mdx title="docs/hello-world.mdx"
# Hello world
{/* LlmsViewOptions component can be added as needed */}
This is a sample document.
```
## Configuration
This plugin accepts an object parameter with the following type:
- **Type**:
```ts
interface LlmsTxt {
name: string;
onTitleGenerate?: (context: {
title: string | undefined;
description: string | undefined;
}) => string;
onLineGenerate?: (page: PageIndexInfo) => string;
onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}
interface MdFiles {
mdxToMd?: boolean;
remarkPlugins?: PluggableList;
}
interface LlmsFullTxt {
name: string;
}
export interface Options {
llmsTxt?: false | LlmsTxt;
mdFiles?: false | MdFiles;
llmsFullTxt?: false | LlmsFullTxt;
include?: (context: { page: PageIndexInfo }) => boolean;
exclude?: (context: { page: PageIndexInfo }) => boolean;
}
```
- **Default**:
When [internationalization](/guide/default-theme/i18n) is not enabled, the default value is:
```ts
{
llmsTxt: { name: 'llms.txt' },
llmsFullTxt: { name: 'llms-full.txt' },
mdFiles: true
}
```
When [internationalization](/guide/default-theme/i18n) is enabled, it will use [multiple configurations](#group), with the default value being:
```ts
[
{
llmsTxt: { name: 'llms.txt' },
llmsFullTxt: { name: 'llms-full.txt' },
mdFiles: true,
include: ({ page }) => page.lang === config.lang,
},
// Automatically generate other languages based on locales configuration
{
llmsTxt: { name: `${lang}/llms.txt` },
llmsFullTxt: { name: `${lang}/llms-full.txt` },
mdFiles: true,
include: ({ page }) => page.lang === lang,
},
// ...
];
```
### llmsTxt
- **Type**: `false | LlmsTxt`
```ts
import type { PageIndexInfo } from '@rspress/core';
export interface LlmsTxt {
name: string;
onTitleGenerate?: (context: {
title: string | undefined;
description: string | undefined;
}) => string;
onLineGenerate?: (page: PageIndexInfo) => string;
onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}
```
- **Default**: `{ name: 'llms.txt' }`
Whether to generate the llms.txt file, or to customize the llms.txt file through hooks.
The default format of an llms.txt file is as follows:
```markdown
# {title}
> {description}
## {nav1.title}
- [{page.title}]({ page.routePath }): {page.frontmatter.description}
## {nav2.title}
- [{page.title}]({ page.routePath }): {page.frontmatter.description}
```
You can modify the specified part through hook.
- `onTitleGenerate`: Customize the generated title and description sections.
- `onLineGenerate`: Customize each line of the md file.
- `onAfterLlmsTxtGenerate`: Finally modify the contents of the llms.txt file.
For example:
```ts
pluginLlms({
llmsTxt: {
onTitleGenerate: ({ title, description }) => {
return `# ${title} - llms.txt
> ${description}
Rspress is a static site generator based on Rsbuild and it can generate llms.txt with @rspress/plugin-llms.
`;
},
},
});
```
The corresponding generation results are:
```markdown
# Rspress - llms.txt
> Rsbuild based static site generator
Rspress is a static site generator based on Rsbuild and it can generate llms.txt with @rspress/plugin-llms.
## guide
- [foo](/foo.md)
```
### mdFiles
- **Type**: `false | MdFiles`
```ts
export interface MdFiles {
mdxToMd?: boolean;
remarkPlugins?: PluggableList;
}
```
- **Default**: `{ mdxToMd: false, remarkPlugins: [] }`
Whether to generate a markdown file for the corresponding route. When set to `false`, the markdown file for the corresponding route will not be generated.
#### mdxToMd
- **Type**: `boolean`
- **Default**: `false`
Whether to convert mdx content to md content. If enabled, mdx files will be converted to md files through a set of default strategies, but there may be some information loss.
#### remarkPlugins
- **Type**: `PluggableList`
- **Default**: `[]`
You can pass in custom remark plugins to modify the Markdown content.
### llmsFullTxt
- **Type**: `false | LlmsFullTxt`
```ts
export interface LlmsFullTxt {
name: string;
}
```
- **Default**: `{ name: 'llms-full.txt' }`
Whether to generate the llms-full.txt file, the `llms-full.txt` file will not be generated when set to `false`.
### include
- **Type**: `(context: { page: PageIndexInfo }) => boolean`
Whether to include certain pages when generated, generally used to simplify llms.txt.
- Example:
Generate `llms.txt` and other related files for pages whose language is English only:
```ts
pluginLlms({
llmsTxt: {
name: 'llms.txt',
},
llmsFullTxt: {
name: 'llms-full.txt',
},
include: ({ page }) => {
return page.lang === 'en';
},
});
```
### exclude
- **Type**: `(context: { page: PageIndexInfo }) => boolean`
Whether to exclude certain pages, it will be executed after `include`.
- Example:
Exclude a single page under the `/foo` route:
```ts
pluginLlms({
llmsTxt: {
name: 'llms.txt',
},
llmsFullTxt: {
name: 'llms-full.txt',
},
exclude: ({ page }) => {
return page.routePath === '/foo';
},
});
```
## UI component props
### LlmsCopyButtonProps
- **Type**: `LlmsCopyButtonProps`
```ts
interface LlmsCopyButtonProps
extends React.ButtonHTMLAttributes {
textByLang?: Record;
text?: string;
}
```
#### textByLang
- **Type**: `Record`
- **Default**: `{ en: 'Copy Markdown', zh: '复制 Markdown' }`
Replace the text on the button according to the corresponding language.
- **Example**:
```mdx
```
#### text
- **Type**: `string`
- **Default**: `''`
Text on the copy button, has higher priority than `textByLang`.
### LlmsViewOptionsProps
- **Type**: `LlmsViewOptionsProps`
```ts
type Option =
| {
title: string;
icon?: React.ReactNode;
onClick?: () => void;
}
| {
title: string;
href: string;
icon?: React.ReactNode;
}
| 'markdownLink'
| 'chatgpt'
| 'claude';
interface LlmsViewOptionsProps
extends React.ButtonHTMLAttributes {
options?: Option[];
textByLang?: Record;
text?: string;
}
```
#### options
- **Type**: `Option[]`
```ts
type Option =
| {
title: string;
icon?: React.ReactNode;
onClick?: () => void;
}
| {
title: string;
href: string;
icon?: React.ReactNode;
}
| 'markdownLink'
| 'chatgpt'
| 'claude';
```
- **Default**: `['markdownLink', 'chatgpt', 'claude']`
Customize the options in the dropdown menu. By default, supports "Copy Markdown Link", [ChatGPT](https://chatgpt.com/) and [Claude](https://claude.ai).
#### textByLang
- **Type**: `Record`
- **Default**: `{ en: 'Open', zh: '打开' }`
Replace the text on the button according to the corresponding language.
#### text
- **Type**: `string`
- **Default**: `''`
Text on the button, has higher priority than `textByLang`.
## Generate multiple groups of `llms.txt` at the same time \{#group}
In some cases, you may generate multiple groups of `llms.txt`, such as i18n sites. At this point, you can do it by passing in an array.
- Example:
```ts
// rspress.config.ts
import { defineConfig } from '@rspress/core';
defineConfig({
lang: 'en',
plugins: [
pluginLlms([
{
llmsTxt: {
name: 'llms.txt',
},
llmsFullTxt: {
name: 'llms-full.txt',
},
include: ({ page }) => page.lang === 'en',
},
{
llmsTxt: {
name: 'zh/llms.txt',
},
llmsFullTxt: {
name: 'zh/llms-full.txt',
},
include: ({ page }) => page.lang === 'zh',
},
]),
],
});
```
---
url: /plugin/official-plugins/sitemap.md
---
# @rspress/plugin-sitemap
import { SourceCode } from '@rspress/core/theme';
Automatically generate [sitemap](https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview) for SEO, which helps search engines crawl your site.
## Installation
import { PackageManagerTabs } from '@theme';
## Usage
Add the following configuration in `rspress.config.ts`:
```ts
// rspress.config.ts
import path from 'path';
import { defineConfig } from '@rspress/core';
import { pluginSitemap } from '@rspress/plugin-sitemap';
export default defineConfig({
plugins: [
pluginSitemap({
siteUrl: 'https://example.com', // Replace with your site URL
}),
],
});
```
## Configuration
This plugin accepts an object parameter with the following type:
```ts
type ChangeFreq =
| 'always'
| 'hourly'
| 'daily'
| 'weekly'
| 'monthly'
| 'yearly'
| 'never';
type Priority =
| '0.0'
| '0.1'
| '0.2'
| '0.3'
| '0.4'
| '0.5'
| '0.6'
| '0.7'
| '0.8'
| '0.9'
| '1.0';
// https://www.sitemaps.org/protocol.html
interface Sitemap {
loc: string;
lastmod?: string;
changefreq?: ChangeFreq;
priority?: Priority;
}
interface CustomMaps {
[routePath: string]: Sitemap;
}
export interface PluginSitemapOptions {
siteUrl?: string;
customMaps?: CustomMaps;
defaultPriority?: Priority;
defaultChangeFreq?: ChangeFreq;
}
```
### siteUrl
- **Type**: `string`
- **Required**
The site URL for deployment access, for example `https://example.com`.
When there is a `base` configuration, `siteUrl` needs to include the `base` path. For example:
```ts
// rspress.config.ts
import path from 'path';
import { defineConfig } from '@rspress/core';
import { pluginSitemap } from '@rspress/plugin-sitemap';
export default defineConfig({
base: '/base/',
plugins: [
pluginSitemap({
siteUrl: 'https://example.com/base/',
}),
],
});
```
### customMaps
- **Type**:
```ts
interface Sitemap {
loc: string;
lastmod?: string;
changefreq?: ChangeFreq;
priority?: Priority;
}
interface CustomMaps {
[routePath: string]: Sitemap;
}
```
- **Default**: `{}`
Used to set custom sitemap values for certain important pages individually.
### defaultChangeFreq
- **Type**: `ChangeFreq`
- **Default**: `'monthly'`
- **Options**: `"always" | "hourly" | "daily" | "weekly" | "monthly" | "yearly" | "never"`
> changefreq: How frequently the page is likely to change. This value provides general information to search engines and may not correlate exactly to how often they crawl the page.
Sets the default [changefreq](https://www.sitemaps.org/protocol.html) value for each page in the generated sitemap file.
### defaultPriority
- **Type**: `Priority`
- **Default**: `'0.5'`
- **Options**: `"0.0" | "0.1" | "0.2" | "0.3" | "0.4" | "0.5" | "0.6" | "0.7" | "0.8" | "0.9" | "1.0"`
> priority: The priority of this URL relative to other URLs on your site.
Sets the default [priority](https://www.sitemaps.org/protocol.html) value for each page in the generated sitemap file.
---
url: /plugin/official-plugins/medium-zoom.md
---
# @rspress/plugin-medium-zoom
import { SourceCode } from '@rspress/core/theme';
Default built-in plugin for supporting image zooming.
## Config
Since this plugin is a built-in plugin, there's no need to manually register it in the config file. You just need to configure it in the `mediumZoom` field. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
mediumZoom: {
selector: '.rspress-doc img',
},
});
```
### selector
- Type: `string`
- Default value: `.rspress-doc img`
Customize the image selector.
### options
- Type: `ZoomOptions`
- Default value: `{}`
Config items for [medium-zoom](https://github.com/francoischalifour/medium-zoom). Click [here](https://github.com/francoischalifour/medium-zoom#options) for more details on the configuration.
---
url: /plugin/official-plugins/client-redirects.md
---
# @rspress/plugin-client-redirects
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
Used for client redirects.
## Precautions
To ensure that the plugin works correctly, you need to set the fallback path in the server's deployment configuration to the `404.html` page generated by Rspress.
For example:
```js title="nginx"
location / {
error_page 404 /404.html;
}
```
```toml title="netlify.toml"
[[redirects]]
from = "/*"
to = "/404.html"
status = 404
```
## Installation
## Usage
Write the following configuration in the configuration file:
```ts title="rspress.config.ts"
import { pluginClientRedirects } from '@rspress/plugin-client-redirects';
import { defineConfig } from '@rspress/core';
export default defineConfig({
pluginClientRedirects({
redirects: [
{
from: '/docs/old1',
to: '/docs/new1',
},
],
}),
});
```
## Configuration
This plugin supports passing in an object configuration. The properties of this object configuration are as follows:
```ts
type RedirectRule = {
from: string | string[];
to: string;
};
type RedirectsOptions = {
redirects?: RedirectRule[];
};
```
`from` represents the matching path, `to` represents the path to be redirected, and using regular expression strings is supported.
:::note
One `to` supports matching multiple `from`: they will redirect to a single path.
One `from` cannot correspond to multiple `to`: there needs to be a unique and clear redirection path.
:::
## Example
```ts
import path from 'node:path';
import { defineConfig } from '@rspress/core';
import { pluginClientRedirects } from '@rspress/plugin-client-redirects';
export default defineConfig({
root: path.join(__dirname, 'doc'),
plugins: [
pluginClientRedirects({
redirects: [
// /docs/old1 -> /docs/new1
{
from: '/docs/old1',
to: '/docs/new1',
},
// redirect from multiple old paths to the new path
{
from: ['/docs/2022', '/docs/2023'],
to: '/docs/2024',
},
// redirect using regular expressions
{
from: '^/docs/old2',
to: '/docs/new2',
},
{
from: '/docs/old3$',
to: '/docs/new3',
},
// redirect to an external URL
{
from: '/docs/old4',
to: 'https://example.com',
},
],
}),
],
});
```
---
url: /plugin/official-plugins/last-updated.md
---
# @rspress/plugin-last-updated
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
## Introduction
`@rspress/plugin-last-updated` is a plugin for displaying the last updated time in articles.
:::tip
- When you have configured `lastUpdated: true` in the default theme, this plugin will be automatically activated. You don't need to install and register it manually.
- You need to commit the markdown file to see the updated time.
:::
## Installation
## Usage
### 1. Register the plugin
```ts title="rspress.config.ts"
import { pluginLastUpdated } from '@rspress/plugin-last-updated';
import { defineConfig } from '@rspress/core';
export default defineConfig({
plugins: [pluginLastUpdated()],
});
```
### 2. Access at runtime
After registering the plugin, you can get the last updated timestamp of the article at runtime. Here's an example:
```ts
import { usePageData } from '@rspress/core/runtime';
function MyComponent() {
const pageData = usePageData();
return
{pageData.page.lastUpdatedTime}
;
}
```
---
url: /plugin/official-plugins/typedoc.md
---
# @rspress/plugin-typedoc
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
Integration of [TypeDoc](https://github.com/TypeStrong/typedoc)'s Rspress Plugin for Automatically Generating API Documentation for TS Modules.
## Installation
## Usage
```ts
import { defineConfig } from '@rspress/core';
import { pluginTypeDoc } from '@rspress/plugin-typedoc';
import path from 'path';
export default defineConfig({
plugins: [
pluginTypeDoc({
entryPoints: [
path.join(__dirname, 'src', 'foo.ts'),
path.join(__dirname, 'src', 'bar.ts'),
],
}),
],
});
```
```ts title="src/foo.ts"
/**
* This is an add function.
*/
export function add(
/**
* This is param1.
*/
param1: string,
/**
* This is param2.
*/
param2: number,
) {
return 1;
}
```
```ts title="src/bar.ts"
/**
* This is a multi function.
*/
export function multi(
/**
* This is param1.
*/
param1?: string,
/**
* This is param2.
*/
param2?: number,
) {
return 1;
}
```
When you start/build the project, the plugin will automatically generate an `api` directory in your document root directory. The directory structure is as follows:
```txt
api
├── README.md
├── documentation.json
├── functions
│ ├── bar.multi.md
│ └── foo.add.md
├── interfaces
│ ├── foo.RunTestsOptions.md
│ └── foo.TestMessage.md
└── modules
├── bar.md
└── foo.md
```
This means that the plugin will internally call TypeDoc to automatically generate API documentation for your modules, including module lists, `Interface` details, function details (parameters, return values, description), etc. It will also generate a `documentation.json` file for subsequent sidebar rendering.
Note that the documentation is regenerated every time you start the project to reflect the latest module content. Therefore, we recommend adding the `api` directory to `.gitignore`. If you customize the output directory with the `outDir` parameter below, you should also add it to `.gitignore`.
Also, we do not recommend modifying or adding documents in the `api` directory because these documents will be overwritten each time the project is started due to changes in module content.
## Parameter description
### entryPoints
- Type: `string[]`
- Default: `[]`
Specifies the absolute path of the TS modules for which documentation should be generated.
### outDir
- Type: `string`
- Default: `api`
Customize the output directory for the documentation. You need to provide a relative path, such as `api/custom`.
---
url: /plugin/official-plugins/api-docgen.md
---
# @rspress/plugin-api-docgen
import { SourceCode } from '@rspress/core/theme';
The plugin is used to generate api document description automatically, powered by [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript) and [documentation](https://github.com/documentationjs/documentation).
## Install
import { PackageManagerTabs } from '@theme';
## Usage
First of all, you need to add following config:
```ts
// rspress.config.ts
import path from 'path';
import { defineConfig } from '@rspress/core';
import { pluginApiDocgen } from '@rspress/plugin-api-docgen';
export default defineConfig({
plugins: [
pluginApiDocgen({
entries: {
button: './src/index.ts',
},
apiParseTool: 'react-docgen-typescript',
}),
],
});
```
Then you can use API component to inject api documentation to your mdx file:
```mdx
## API
This is API Table
```
## Config
The plugin accepts an object, which has the following types:
```ts
interface Options {
entries?: Record;
apiParseTool?: 'react-docgen-typescript' | 'documentation';
appDir?: string;
parseToolOptions?: ParseToolOptions;
}
```
### appDir
`appDir` is used to configure the base directory for parsing,default `process.cwd()`.
### entries
`entries` is used to configure the basic info for parsing.
- key is an identifier that serves as the `moduleName` attribute of the API component.
- value is the relative path to the parsed file.
### apiParseTool
`apiParseTool` is used to choose the tool for parsing,default `react-docgen-typescript`:
- `react-docgen-typescript`is used for component library scenarios, only props will be parsed to generate tables.
```tsx
export type ButtonProps = {
/**
* Whether to disable the button
*/
disabled?: boolean;
/**
* Type of Button
* @default 'default'
*/
size?: 'mini' | 'small' | 'default' | 'large';
};
export const Button = (props?: ButtonProps) => {};
```
The above is a standard writeup where `ButtonProps` will be extracted into the form and `Button` will be used as the form title.
If you use the default export, the filename will be used as the form title.
Notice that export features declared elsewhere are not available.
```tsx
const A = () => {};
export { A }; // wrong
export default A; // wrong
export const B = () => {}; // right
export default () => {}; // right
```
The generated content is as follows:
```mdx
### ButtonTest
| Props | Description | Type | Default |
| :------: | :---------------------------: | :-----------------------------------------: | :---------: |
| disabled | Whether to disable the button | `boolean` | `-` |
| size | Type of Button | `"mini" \| "small" \| "default" \| "large"` | `'default'` |
```
:::warning
If React types are used in Props, you need to add the types in tsconfig.json, otherwise the types will not be resolved under the React namespace.
```json
{
"compilerOptions": {
"types": ["react"]
}
}
```
The best way is that you import the type directly:
```tsx
import { FC } from 'react';
```
:::
- `documentation` is used in tool library scenarios to parse JSDoc annotations.
Here is a greet function with JSDoc annotations.
```ts
/**
* Greet function that returns a greeting message.
* @param {string} name - The name of the person to greet.
* @param {string} [greeting='Hello'] - The greeting to use.
* @returns {string} The greeting message.
*/
function greet(name: string, greeting = 'Hello') {
return `${greeting}, ${name}!`;
}
```
The generated content is as follows:
```md
## greet
Greet function that returns a greeting message.
### Parameters
- `name` **[string][1]** The name of the person to greet.
- `greeting` **[string][1]** The greeting to use. (optional, default `'Hello'`)
Returns **[string][1]** The greeting message.
[1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
```
### parseToolOptions
`parseToolOptions` is used to pass options to the corresponding parse tool, whose types are as follows:
```ts
type ParseToolOptions = {
'react-docgen-typescript'?: ParserOptions & {
tsconfigPath?: Record;
compilerOptions?: Record;
};
documentation?: DocumentationArgs;
};
```
Please refer to [ParserOptions](https://github.com/styleguidist/react-docgen-typescript/blob/b7ea0a235efb7c78a1158ca12d864de2bc2ee30e/src/parser.ts#L84-L95) and [DocumentationArgs](https://github.com/documentationjs/documentation/blob/master/docs/NODE_API.md#parameters-1) to learn about available options.
If the parser is `react-docgen-typescript`, the `withDefaultConfig` method is used by default to create a parser instance. If `tsconfigPath` or `compilerOptions` is configured, `tsconfigPath` and `compilerOptions` can be set separately for each `entry`, the `withCompilerOptions` and `withCustomConfig` methods are used to create the parser instance respectively. See [Custom Parsers](https://github.com/styleguidist/react-docgen-typescript/blob/b7ea0a235efb7c78a1158ca12d864de2bc2ee30e/README.md#usage) for details.
---
url: /plugin/official-plugins/preview.md
---
# @rspress/plugin-preview
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
Used to preview components in the code block of md(x) files.
## Installation
## Usage
### Register
First, write the following config in the config file:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginPreview } from '@rspress/plugin-preview';
export default defineConfig({
plugins: [pluginPreview()],
});
```
:::warning Note
This plugin will set `markdown.mdxRs` to `false`. In the future, the Rspress team will port this plugin to the Rust version of the compiler.
:::
### Internal components
The component code of internal components is declared in the mdx file. You can declare the following code block in the mdx file:
````md
```tsx
function App() {
return
Hello World
;
}
export default App;
```
````
It's worth noting that you need to export the component as default, and Rspress will automatically render this component.
But if you want to keep the style of the code block instead of rendering it as a component, you can add the `pure` identifier to specify, the usage is as follows:
````md
```tsx pure
function App() {
return
Hello World
;
}
export default App;
```
````
If you have set `defaultRenderMode` to `'pure'`, Rspress will not render this component by default, but instead display it as a code block. If you want to render a code block as a component in this situation, you can do add the `preview` identifier to specify, the usage is as follows:
````md
```tsx preview
function App() {
return
Hello World
;
}
export default App;
```
````
:::tip Tip
Make sure the document ends with `.mdx`.
:::
### External components
In addition to writing component code in the code block of the mdx file, you can also write component code in an external file and then import it in the mdx file through the meta tag of `file="./filename"`. For example
````md title="example.mdx"
```tsx file="./Demo.tsx"
```
````
```tsx title="Demo.tsx"
export default function App() {
return
Hello World
;
}
```
External components also need to export the component as default. Through the src attribute of the code tag, you can specify the path of the external component. This plugin supports both relative paths and alias paths(alias).
For some more complex components, this way of using external components will be more convenient.
## Options
This plugin accepts an object parameter of the following type:
```ts
interface PreviewOptions {
previewMode?: 'internal' | 'iframe';
iframeOptions?: IframeOptions;
defaultRenderMode?: 'pure' | 'preview';
}
interface IframeOptions {
framework?: 'react' | 'solid';
position?: 'fixed' | 'follow';
devPort?: number;
}
```
### defaultRenderMode
The default mode of rendering internal code blocks that do not have the `pure` or `preview` identifiers declared by users, defaulting to `preview`.
- `pure`: render as regular code block
- `preview`: render as component
### previewMode
The `previewMode` parameter is used to specify whether the preview mode is internal, defaulting to `internal`. The default mode display effect is as follows:

You can also set it for each individual code block:
````md title="example.mdx"
```tsx iframe
function App() {
return
Hello World
;
}
export default App;
```
````
````md title="example.mdx"
```tsx file="./demo.tsx" iframe
```
````
If previewMode is `iframe`, you can use the following configuration for the iframe:
### iframeOptions.position
In iframe preview mode, you can use the `iframeOptions.position` parameter to determine the position of the preview area iframe, whether it follows page scrolling (`follow` mode) or is fixed on the page (`fixed` mode), defaulting to `follow`.
The effect of `follow` mode is as follows:

The effect of `fixed` mode is as follows:

### iframeOptions.framework
In iframe preview mode, you can choose the rendering framework, currently supports `react` and `solid`.
### iframeOptions.devPort
In the iframe preview mode, you can configure the dev server port of the preview component.
### iframeOptions.builderConfig
Configure the buildConfig of the iframe, such as adding some global code.
### iframeOptions.customEntry
Configure custom entry to support other `Web` frameworks, such as `Vue`.
Use customEntry only `iframeOptions.position = follow`.
```ts
import { defineConfig } from '@rspress/core';
import { pluginPreview } from '@rspress/plugin-preview';
import { pluginVue } from '@rsbuild/plugin-vue';
export default defineConfig({
// ...
plugins: [
pluginPreview({
previewMode: 'iframe',
previewLanguages: ['vue'],
iframeOptions: {
position: 'follow',
customEntry: ({ entryCssPath, demoPath }) => {
return `
import { createApp } from 'vue';
import App from ${JSON.stringify(demoPath)};
import ${JSON.stringify(entryCssPath)};
createApp(App).mount('#root');
`;
},
builderConfig: {
plugins: [pluginVue()],
},
},
}),
],
});
```
### deprecated: isMobile
From v1.12.0, please use [previewMode](#previewmode) instead.
### deprecated: iframePosition
From v1.12.0, please use [iframeOptions.position](#iframeoptionsposition) instead.
### previewLanguages
- Type: `string[]`
- Default: `['jsx', 'tsx']`
The code languages that support preview, by default jsx and tsx codes are supported. If you need to support other formats of code, such as json/yaml, you can use it in conjunction with the `previewCodeTransform` configuration below.
### previewCodeTransform
- Type: `(codeInfo: { language: string; code: string }) => string`
- default: `({ code }) => code`
Customize the transformation of the code before previewing. For example, if you want to render a piece of JSON Schema through custom transformation logic:
```json
{
"type": "div",
"children": "Render from JSON"
}
```
You can make the following configuration:
```ts
pluginPreview({
// Note to add the default jsx and tsx
previewLanguages: ['jsx', 'tsx', 'json'],
previewCodeTransform(codeInfo) {
if (codeInfo.language === 'json') {
return `
import React from 'react';
const json = ${codeInfo.code};
export default function() {
return React.createElement(json.type, null, json.children);
}
`;
} else {
return codeInfo.code;
}
},
});
```
In this way, the component code after custom logic transformation will be rendered in the end.
:::warning Note
The `previewLanguages` and `previewCodeTransform` configurations only take effect for internal components, that is, they take effect for code blocks declared in mdx files, but they do not take effect for external files declared in `code` tags!
:::
---
url: /plugin/official-plugins/playground.md
---
# @rspress/plugin-playground
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
Provide a real-time playground to preview the code blocks in MDX files.
## Installation
## Usage
### Register
First, write the following config in the config file:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginPlayground } from '@rspress/plugin-playground';
export default defineConfig({
plugins: [pluginPlayground()],
});
```
:::warning Note
This plugin will set `markdown.mdxRs` to `false`. In the future, the Rspress team will port this plugin to the Rust version of the compiler.
:::
### Internal components
:::tip Note
It is recommended to use js or jsx to write sample code to avoid ts type errors in the editor.
:::
The component code of internal components is declared in the mdx file. This plugin supports jsx and tsx. You can declare the following code block in the mdx file:
````mdx
```jsx
import React from 'react';
function App() {
return
Hello World
;
}
export default App;
```
````
Otherwise, You can use `direction` parameter to specify the playground layout, `horizontal` and `vertical` are supported:
````mdx
```jsx direction=vertical
import React from 'react';
function App() {
return
Hello World
;
}
export default App;
```
````
It's worth noting that you need to export the component as default, and Rspress will automatically render this component.
But if you want to keep the style of the code block instead of rendering it as a component, you can add the `pure` identifier to specify, the usage is as follows:
````mdx
```tsx pure
import React from 'react';
function App() {
return
Hello World
;
}
export default App;
```
````
If you have set `defaultRenderMode` to `'pure'`, Rspress will not render this component by default, but instead display it as a code block. If you want to render a code block as a component in this situation, you can do add the `preview` identifier to specify, the usage is as follows:
````mdx
```tsx playground
function App() {
return
Hello World
;
}
export default App;
```
````
:::tip Tip
Make sure the document ends with `.mdx`.
:::
### External components
In addition to writing component code in the code block of the mdx file, you can also write component code in an external file and then import it in the mdx file through the meta tag of `file="./filename"`. For example
````md title="example.mdx"
```jsx file="./Demo.jsx"
```
````
```jsx title="Demo.jsx"
import React from 'react';
export default function App() {
return
Hello World
;
}
```
Same as internal components, external components also support `direction` attribute:
````md title="example.mdx"
```jsx file="./Demo.jsx" direction=vertical
```
````
External components also need to export the component as default. Through the src attribute of the code tag, you can specify the path of the external component. This plugin supports both relative paths and alias paths(alias).
For some more complex components, this way of using external components will be more convenient.
### Define the layout of the entire page
You can write `playgroundDirection` in frontmatter to define the layout of the editor and preview area in the entire page.
```md title="example.mdx"
---
title: title
playgroundDirection: horizontal
---
```
Priority: Defined directly on the preview area > Page Definition > Configuration.
## Configuration
This plugin accepts an object parameter, the type is as follows:
```ts
interface PlaygroundOptions {
render: string;
include: Array;
// Define the default playground layout (horizontal/vertical)
defaultDirection: 'horizontal' | 'vertical';
// Define the position of the editor in horizontal layout (left/right)
editorPosition: 'left' | 'right';
// Default editor (monaco) partial configuration
monacoLoader: Parameters[0];
monacoOptions: MonacoEditorProps['options'];
}
```
:::warning Note
`monacoLoader` and `monacoOptions` will be serialized to JSON, so some data types, such as functions and circularly referenced objects, are not supported.
:::
### render
You can customize the render file for rendering Playground. Please note that the file name must be `Playground.(jsx?|tsx?)`
```ts
pluginPlayground({
render: '/path/to/render/Playground.tsx',
});
```
In the custom playground, you can directly import the original editor and renderer, and import pre-packaged dependencies through `_rspress_playground_imports`:
```ts
import getImport from '_rspress_playground_imports';
import { Runner, Editor } from '@rspress/plugin-playground/web';
```
You can refer to the built-in [Playground.tsx](https://github.com/web-infra-dev/rspress/tree/main/packages/plugin-playground/static/global-components/Playground.tsx).
### include
By default, this plugin will automatically scan all import statements in the demos, the packages not used in the demos cannot be used in the playground. If you want to add other packages to the playground, you can use the `include` parameter:
```ts
pluginPlayground({
include: [
// Add dayjs package
'dayjs',
// Add a package named "my-package", and it actual reference to "/path/to/package/index.js"
['my-package', '/path/to/package/index.js'],
],
});
```
### babelUrl
Playground uses `@babel/standalone` to compile the demo code, loaded from [cdnjs.com](https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.22.20/babel.min.js) by default.
You can modify the URL served to other CDNs, such as unpkg, jsdelivr, etc.
### monacoLoader
Configure monaco-loader behaviors, loaded from [cdnjs.com](https://cdnjs.com/libraries/monaco-editor) by default.
You can modify the URL served to other CDNs, such as unpkg, jsdelivr, etc.
The full document can be found at [suren-atoyan/monaco-loader](https://github.com/suren-atoyan/monaco-loader#config)
### monacoOptions
Configure monaco editor, corresponding to [IStandaloneEditorConstructionOptions](https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html)
### defaultRenderMode
The default mode of rendering internal code blocks that do not have the `pure` or `playground` identifiers declared by users, defaulting to `playground`.
- `pure`: render as regular code block
- `playground`: render as Playground component
---
url: /plugin/official-plugins/rss.md
---
# @rspress/plugin-rss
import { SourceCode, PackageManagerTabs } from '@rspress/core/theme';
Generates RSS files for specific document pages with [feed](https://github.com/jpmonette/feed).
## Installation
### Update Rspress config
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginRss } from '@rspress/plugin-rss';
export default defineConfig({
plugins: [
pluginRss({
// The URL of your document site
siteUrl: 'https://example.com',
// ...more configurations below
}),
],
});
```
By default, this plugin generates a `blog.xml` file in the `doc_build/rss/` folder for all pages starting with `/blog/`.
The RSS file can be accessed via `/rss/blog.xml`.
:::tip
This plugin only works with `rspress build` and does not generate RSS files on `rspress dev`.
:::
## Usage
### Selecting pages to be included in RSS
Use the `feed.test` option to select which pages to be included in the RSS file.
```ts
pluginRss({
// ...
feed: { test: '/zh/blog' },
});
```
### Requirements
All documents included in the RSS must have either `date` or `published_at` in their frontmatter to ensure that the RSS updates are stable on the user side.
```md
---
published_at: 2024-01-10 08:00:00
---
Or frontmatter `date`.
```
### Generating multiple RSS files
Sometimes, you may need to generate multiple RSS files for, e.g., different languages or categories.
You can provide a list of RSS options to the `feed` option. For instance:
```ts
pluginRss({
feed: [
{ id: 'blog', test: '/blog/', title: 'Rspress Blog', language: 'en-US' },
{
id: 'blog-zh',
test: '/zh/blog/',
title: 'Rspress 博客',
language: 'zh-CN',
},
{
id: 'rspack',
test: ({ frontmatter }) => frontmatter.categories.includes('rspack'),
title: 'Rspack Releases',
language: 'en-US',
},
{
id: 'rsbuild',
test: ({ frontmatter }) => frontmatter.categories.includes('rsbuild'),
title: 'Rsbuild Releases',
language: 'en-US',
},
],
});
```
The options above will generate four RSS files: `blog.xml`, `blog-zh.xml`, `rspack.xml`, `rsbuild.xml`, all located in the `rss` folder.
### Modifying the output path
You can customize the output path using the `output` and `feed.output` parameters.
Please refer to the [FeedOutputOptions](#feedoutputoptions) below.
### Linking RSS to document pages
By default, this plugin will insert a `` tag in the selected pages that are included in the RSS, linking to the URL of the RSS file. RSS readers can automatically detect the RSS URL.
If you want to insert this tag in pages that are not included in the RSS (such as the homepage), you can add the `link-rss` frontmatter to the document, with the value being the feed id. For example:
```markdown
---
link-rss: blog
---
This frontmatter will insert a `` tag in the page of this document, pointing to the RSS URL of the `blog` feed.
However, this page itself will not be included in that RSS.
```
`link-rss` also supports inserting multiple `` tags associated with feed ids on a single page:
```markdown
---
link-rss:
- blog
- releases
---
```
### Cook the RSS content
The RSS file consists of two parts: the RSS basic information, known as the `channel` in the RSS format, and the list of articles, known as the `item` in the RSS format.
Here's how you can cook each part:
- The `channel` can be fully modified through the `feed` parameter. Please refer to the [Other Options](#other-options) below.
- The `item` can be fully modified through the `feed.item` parameter. Please refer to the [item](#item) section below.
## Options
### PluginRssOptions
Options of the plugin.
```ts
export interface PluginRssOptions {
siteUrl: string;
feed?: Partial | FeedChannel[];
output?: Omit;
}
```
#### `siteUrl`
- **Type**: `string`
- **Required**
The site URL of the current document site. It will be used in the RSS file.
When there is a `base` configuration, `siteUrl` needs to include the `base` path. For example:
```ts
// rspress.config.ts
import path from 'path';
import { defineConfig } from '@rspress/core';
import { pluginRss } from '@rspress/plugin-rss';
export default defineConfig({
base: '/base/',
plugins: [
pluginRss({
siteUrl: 'https://example.com/base/',
}),
],
});
```
#### `feed`
- **Type**: `FeedChannel | FeedChannel[]`
- **Default**: `{ id: 'blog', test: '/blog/' }`
RSS configuration, multiple value array can generate multiple RSS files.
See [FeedChannel](#feedchannel) for more information.
#### `output`
- **Type**: `Omit`
- **Default**: `{ dir: 'rss', type: 'atom' }`
Options for document output. Please refer to [FeedOutputOptions](#feedoutputoptions) below.
### FeedChannel
Options for RSS file.
```ts
export interface FeedChannel extends Partial {
id: string;
test:
| RegExp
| string
| (RegExp | string)[]
| ((item: PageIndexInfo, base: string) => boolean);
item?: (
item: FeedItem,
page: PageIndexInfo,
siteUrl: string,
) => FeedItem | PromiseLike;
output?: FeedOutputOptions;
}
```
#### `id`
- **Type**: `string`
- **Required**
The ID of an RSS, unique among multiple RSS options. It is also the default file basename for the RSS file.
#### `test`
- **Type**: `RegExp | string | (RegExp | string)[] | ((item: PageIndexInfo, base: string) => boolean)`
- **Required**
Used to select documents to be included in the RSS. The types are as follows:
- `RegExp`: Regular expression to match the document's route. When the rspress site has `base` configured, it will match both routes with and without the `base` path.
- `string`: Prefix-based matching to the document's route. When the rspress site has `base` configured, it will match both routes with and without the `base` path.
- `(item: PageIndexInfo, base: string) => boolean`: Match pages based on page data and frontmatter.
#### `item`
- **Type**: `(item: FeedItem, page: PageIndexInfo, siteUrl: string) => FeedItem | PromiseLike`
- **Default**: Elaborated below
Generates structured data for each article in the RSS file.
Refer to the type of structured data:
The plugin has a built-in generator that utilizes the document's frontmatter and page data.
For example, the `content` in the RSS will prioritize the `summary` from frontmatter, and then try the document content.
You can provide the `item` function to modify the generated data which will be passed as the first parameter to the function you provided.
For example, the following configuration truncates the content of articles in the RSS:
```ts
const item: FeedChannel['item'] = (item) => ({
...item,
content: item.content.slice(0, 1000),
});
```
For details on the logic of the built-in generator, please refer to:
#### `output`
- **Type**: `FeedOutputOptions`
- **Default**: Uses the plugin's `output` option by default
In addition to the plugin's `output` option, there is an additional `filename` to modify the output filename.
Please refer to [FeedOutputOptions](#feedoutputoptions) below.
#### Other options
`FeedChannel` also inherits the `FeedOptions` from the feed package. Please refer to for parameters that are not listed.
### FeedOutputOptions
Output options for RSS files, available at both the top level of the plugin options and the `feed` level. Using the following type:
```ts
interface FeedOutputOptions {
dir?: string;
type?: 'atom' | 'rss' | 'json';
filename?: string;
publicPath?: string;
sorting?: (left: FeedItem, right: FeedItem) => number;
}
```
Example:
```ts
pluginRss({
// Applied to all RSS outputs
output: {
// Change the output folder for RSS files to 'feeds', relative to `doc_build`
dir: 'feeds',
// Output in RSS 2.0 format, use `.rss` extension by default.
type: 'rss',
},
feed: [
{
id: 'blog',
test: '/blog/',
title: 'My Blog',
output: {
type: 'atom' /* default to using `id` as the base file name */,
},
},
{
id: 'releases',
test: '/releases/',
title: 'Releases',
output: { dir: 'releases', filename: 'feed.rss' },
},
],
});
```
Building with the options above will output two files: `feeds/blog.xml` and `releases/feed.rss`.
#### `dir`
- **Type**: `string`
- **Default**: `rss`
Output folder for RSS files, relative to `doc_build`.
#### `type`
- **Type**: `"atom" | "rss" | "json"`
- **Default**: `atom`
Output format of the RSS file, `atom` by default. Details of these types:
| Value | Format | Default Extension | MIME Type |
| ------ | ------------------------------------------------------ | ----------------- | ---------------------- |
| `atom` | [Atom 1.0](https://www.ietf.org/rfc/rfc4287.txt) | `.xml` | `application/atom+xml` |
| `rss` | [RSS 2.0](https://www.rssboard.org/rss-specification) | `.rss` | `application/rss+xml` |
| `json` | [JSON Feed 1.1](https://www.jsonfeed.org/version/1.1/) | `.json` | `application/json` |
#### `filename`
- **Type**: `string`
- **Default**: ID as the file basename; extension by RSS output format
Modify the full filename of the RSS file.
#### `publicPath`
- **Type**: `string`
- **Default**: the value of `siteUrl`
URL Prefix for the RSS file. An RSS URL is composed of `publicPath`, `dir`, and `filename`.
#### `sorting`
- **Type**:`sorting?: (left: FeedItem, right: FeedItem) => number;`
Used for sorting the articles. By default, the newest articles go first, followed by the older ones.
---
url: /plugin/official-plugins/algolia.md
---
# @rspress/plugin-algolia
import { SourceCode } from '@rspress/core/theme';
Based on [docsearch](https://docsearch.algolia.com), this plugin replaces Rspress's built-in search with [algolia](https://www.algolia.com/).
## Installation
import { PackageManagerTabs } from '@theme';
## Usage
First, add the following configuration to `rspress.config.ts`:
```ts
// rspress.config.ts
import path from 'path';
import { defineConfig } from '@rspress/core';
import { pluginAlgolia } from '@rspress/plugin-algolia';
export default defineConfig({
plugins: [pluginAlgolia()],
});
```
Then override the `Search` component with an algolia-supported search box via [Custom Theme](/ui/custom-theme).
```tsx
// theme/index.tsx
import { Search as PluginAlgoliaSearch } from '@rspress/plugin-algolia/runtime';
const Search = () => {
return (
);
};
export { Search };
export * from '@rspress/core/theme';
```
## Configuration
The plugin accepts an options object with the following type:
```ts
interface Options {
verificationContent?: string;
}
```
### verificationContent
- Type: `string | undefined`
- Default: `undefined`
Used for meta tag verification when creating algolia crawler. Format: ``. Refer to [Create a new crawler - algolia](https://www.algolia.com/doc/tools/crawler/getting-started/create-crawler/#dns)
## SearchProps
The `SearchProps` type from `@rspress/plugin-algolia/runtime` is as follows:
```ts
import type { DocSearchProps } from '@docsearch/react';
type Locales = Record<
string,
{ translations: DocSearchProps['translations']; placeholder: string }
>;
type SearchProps = {
/**
* @link https://docsearch.algolia.com/docs/api
*/
docSearchProps?: DocSearchProps;
locales?: Locales;
};
```
### docSearchProps
- Type: `import('@docsearch/react').DocSearchProps`
- Default: `undefined`
`docSearchProps` will be directly passed to the `` component in `@docsearch/react`. For specific types, please refer to [docsearch documentation](https://docsearch.algolia.com/docs/api).
### locales
- Type:
```ts
type Locales = Record<
string,
{ translations: DocSearchProps['translations']; placeholder: string }
>;
```
- Default: `{}`
For customizing translated text in different languages, Rspress provides the following translated text, which can be imported through import.
```ts
export const ZH_LOCALES: Locales = {
zh: {
placeholder: '搜索文档',
translations: {
button: {
buttonText: '搜索',
buttonAriaLabel: '搜索',
},
modal: {
searchBox: {
clearButtonTitle: '清除查询条件',
clearButtonAriaLabel: '清除查询条件',
closeButtonText: '取消',
closeButtonAriaLabel: '取消',
},
startScreen: {
recentSearchesTitle: '搜索历史',
noRecentSearchesText: '没有搜索历史',
saveRecentSearchButtonTitle: '保存至搜索历史',
removeRecentSearchButtonTitle: '从搜索历史中移除',
favoriteSearchesTitle: '收藏',
removeFavoriteSearchButtonTitle: '从收藏中移除',
},
errorScreen: {
titleText: '无法获取结果',
helpText: '你可能需要检查你的网络连接',
},
footer: {
selectText: '选择',
navigateText: '切换',
closeText: '关闭',
poweredByText: '搜索提供者',
},
noResultsScreen: {
noResultsText: '无法找到相关结果',
suggestedQueryText: '你可以尝试查询',
reportMissingResultsText: '你认为该查询应该有结果?',
reportMissingResultsLinkText: '点击反馈',
},
},
},
},
} as const;
```
Rspress provides Chinese translation by default, and you can customize translated text in different languages through `locales`.
- Example:
```tsx
import { Search as PluginAlgoliaSearch, ZH_LOCALES } from '@rspress/plugin-algolia/runtime';
// or
```
## Algolia crawler config
Here is an example config based on what this site uses:
```tsx
new Crawler({
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_API_KEY',
rateLimit: 8,
maxDepth: 10,
startUrls: ['https://rspress.rs'],
sitemaps: ['https://rspress.rs/sitemap.xml'],
discoveryPatterns: ['https://rspress.rs/**'],
actions: [
{
indexName: 'doc_search_rspress_pages',
pathsToMatch: ['https://rspress.rs/**'],
recordExtractor: ({ $, helpers }) => {
const lvl0 =
$('.rspress-nav-menu-item.rspress-nav-menu-item-active')
.first()
.text() || 'Documentation';
return helpers.docsearch({
recordProps: {
lvl0: {
selectors: '',
defaultValue: lvl0,
},
lvl1: '.rspress-doc h1',
lvl2: '.rspress-doc h2',
lvl3: '.rspress-doc h3',
lvl4: '.rspress-doc h4',
lvl5: '.rspress-doc h5',
lvl6: '.rspress-doc pre > code', // if you want to search code blocks, add this line
content: '.rspress-doc p, .rspress-doc li',
},
indexHeadings: true,
aggregateContent: true,
recordVersion: 'v3',
});
},
},
],
initialIndexSettings: {
doc_search_rspress_pages: {
attributesForFaceting: ['type', 'lang'],
attributesToRetrieve: [
'hierarchy',
'content',
'anchor',
'url',
'url_without_anchor',
'type',
],
attributesToHighlight: ['hierarchy', 'content'],
attributesToSnippet: ['content:10'],
camelCaseAttributes: ['hierarchy', 'content'],
searchableAttributes: [
'unordered(hierarchy.lvl0)',
'unordered(hierarchy.lvl1)',
'unordered(hierarchy.lvl2)',
'unordered(hierarchy.lvl3)',
'unordered(hierarchy.lvl4)',
'unordered(hierarchy.lvl5)',
'unordered(hierarchy.lvl6)',
'content',
],
distinct: true,
attributeForDistinct: 'url',
customRanking: [
'desc(weight.pageRank)',
'desc(weight.level)',
'asc(weight.position)',
],
ranking: [
'words',
'filters',
'typo',
'attribute',
'proximity',
'exact',
'custom',
],
highlightPreTag: '',
highlightPostTag: '',
minWordSizefor1Typo: 3,
minWordSizefor2Typos: 7,
allowTyposOnNumericTokens: false,
minProximity: 1,
ignorePlurals: true,
advancedSyntax: true,
attributeCriteriaComputedByMinProximity: true,
removeWordsIfNoResults: 'allOptional',
},
},
});
```
## Distinguish search results based on i18n
You can achieve internationalized search results by combining [Runtime API](/api/client-api/api-runtime) with `docSearchProps`.
Here's an example using `docSearchProps.searchParameters`:
```tsx
// theme/index.tsx
import { useLang } from '@rspress/core/runtime';
import { Search as PluginAlgoliaSearch } from '@rspress/plugin-algolia/runtime';
const Search = () => {
const lang = useLang();
return (
);
};
export { Search };
export * from '@rspress/core/theme';
```
---
url: /plugin/official-plugins/twoslash.md
---
# @rspress/plugin-twoslash
import { SourceCode, PackageManagerTabs, Tabs, Tab } from '@theme';
Integration of [Twoslash](https://github.com/twoslashes/twoslash)'s Rspress Plugin for automatically generating rich code blocks with type information.
## Installation
## Usage
### 1. Register the plugin
```ts twoslash title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginTwoslash } from '@rspress/plugin-twoslash';
export default defineConfig({
plugins: [pluginTwoslash()],
});
```
### 2. Write code blocks with twoslash
Use special comments within TypeScript code blocks to enable Twoslash features.
For more detailed usage, please refer to the [Twoslash documentation](https://twoslash.netlify.app/guide/).
#### Extract type
```ts twoslash
const hi = 'Hello';
const msg = `${hi}, world`;
// ^?
```
````mdx
```ts twoslash
const hi = 'Hello';
const msg = `${hi}, world`;
// ^?
```
````
#### Completions
```ts twoslash
// @noErrors
console.e;
// ^|
```
````mdx
```ts twoslash
// @noErrors
console.e;
// ^|
```
````
#### Highlighting
```ts twoslash
function add(a: number, b: number) {
// ^^^
return a + b;
}
```
````mdx
```ts twoslash
function add(a: number, b: number) {
// ^^^
return a + b;
}
```
````
#### Error
```ts twoslash
// @noErrorValidation
const str: string = 1;
```
````mdx
```ts twoslash
// @noErrorValidation
const str: string = 1;
```
````
## Config
The plugin accepts an object with the following type:
```ts twoslash
export interface PluginTwoslashOptions {
explicitTrigger?: boolean;
}
```
### explicitTrigger
`explicitTrigger` is used to configure whether to explicitly trigger the Twoslash feature. Default is `true`.
- If set to `false`, all TypeScript code blocks will be processed by default.
- If set to `true`, only code blocks with the `twoslash` tag will be processed.
---
url: /plugin/community-plugins/overview.md
---
# Overview
## Community plugins
Community plugins include:
- [rspress-plugin-translate](https://github.com/byteHulk/rspress-plugin-translate): A plugin that integrates LLM for document translation.
- [rspress-plugin-font-open-sans](https://github.com/rspack-contrib/rspress-plugin-font-open-sans): Use Open Sans as the default font in your Rspress website.
Rspress website.
- [rspress-plugin-align-image](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-align-image): Rspress plugin to align images in markdown.
- [rspress-plugin-directives](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-directives): Rspress plugin for custom directives support.
- [rspress-plugin-file-tree](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-file-tree): Rspress plugin that add tree view for file structure display.
- [rspress-plugin-gh-pages](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-gh-pages): Rspress plugin to add support for automatic deployment to GitHub Pages.
- [rspress-plugin-google-analytics](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-google-analytics): Rspress plugin for Google Analytics integration.
- [rspress-plugin-vercel-analytics](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-vercel-analytics): Rspress plugin for Vercel Analytics integration.
- [rspress-plugin-katex](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-katex): Rspress plugin to add support for rendering math equations using [KaTeX](https://katex.org/).
- [rspress-plugin-live2d](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-live2d): Rspress plugin for live2d, powered by [on-my-live2d](https://oml2d.com/).
- [rspress-plugin-mermaid](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-mermaid): Rspress plugin to render [Mermaid](https://mermaid.js.org/#/) diagrams in markdown files.
- [rspress-plugin-reading-time](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-reading-time): Rspress plugin to display reading time for your document pages.
- [rspress-plugin-supersub](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-supersub): Rspress plugin to add superscript(``) and subscript(``) support.
- [rspress-plugin-toc](https://github.com/rspack-contrib/rspress-plugins/tree/main/packages/rspress-plugin-toc): Rspress plugin that injects a table of contents into the page.
You can check out the Rspress plugins provided by the community at [awesome-rspack - Rspress Plugins](https://github.com/web-infra-dev/awesome-rspack?tab=readme-ov-file#rspress-plugins).
You can also discover more Rspress plugins on npm by searching for the keyword [rspress-plugin](https://www.npmjs.com/search?q=rspress-plugin&ranking=popularity).
---
url: /ui/vars.md
---
# CSS variables
:::warning 🚧 Still under development
:::
## Brand css variables
import { CssPickerEditor } from '../../components/CssPickerEditor';
## Shiki theme css variables
import { ShikiThemeSwitcher } from '../../components/ShikiThemeSwitcher';
---
url: /ui/custom-theme.md
---
# Custom theme
This article will tell you how to develop custom theme.
## Extensions based on the default theme
In most cases, you don't want to develop a theme from scratch, but want to extend it based on the default theme. At this time, you can refer to the following methods for theme development.
:::tip
If you want to develop a custom theme from scratch, you can go to [Redevelop a custom theme](/ui/custom-theme#redevelop-a-custom-theme).
:::
### 1. Basic structure
By default, you need to create a `theme` directory under the project root directory, and then create an `index.ts` or `index.tsx` file under the `theme` directory, which is used to export the theme content.
```txt
└── theme
└── index.tsx
```
You can write the `theme/index.tsx` file as follows:
```tsx title="theme/index.tsx"
import { Layout as BasicLayout } from '@rspress/core/theme';
const Layout = () => some content} />;
export { Layout };
export * from '@rspress/core/theme';
```
On the one hand, you need to export a theme configuration object through `export`, on the other hand, you need to export all named exported content through `export * from '@rspress/core/theme'` so as to ensure your theme works fine.
### 2. Use slot
It is worth noting that the `Layout` component has designed a series of props to support slot elements. You can use these props to extend the layout of the default theme. For example, change the above `Layout` component to the following form:
```tsx title="theme/index.tsx"
import { Layout as BasicLayout } from '@rspress/core/theme';
// Show all props below
const Layout = () => (
beforeHero}
/* After home hero */
afterHero={
afterHero
}
/* Before home features */
beforeFeatures={
beforeFeatures
}
/* After home features */
afterFeatures={
afterFeatures
}
/* Before doc footer */
beforeDocFooter={
beforeDocFooter
}
/* After doc footer */
afterDocFooter={
afterDocFooter
}
/* Doc page front */
beforeDoc={
beforeDoc
}
/* Doc page end */
afterDoc={
afterDoc
}
/* Doc content front */
beforeDocContent={
beforeDocContent
}
/* Doc content end */
afterDocContent={
afterDocContent
}
/* Before the nav bar */
beforeNav={
beforeNav
}
/* Before the title of the nav bar in the upper left corner */
beforeNavTitle={😄}
/* Nav bar title */
navTitle={
Custom Nav Title
}
/* After the title of the nav bar in the upper left corner */
afterNavTitle={
afterNavTitle
}
/* The right corner of the nav menu */
afterNavMenu={
afterNavMenu
}
/* Above the left sidebar */
beforeSidebar={
beforeSidebar
}
/* Below the left sidebar */
afterSidebar={
afterSidebar
}
/* Above the right outline column */
beforeOutline={
beforeOutline
}
/* Below the outline column on the right */
afterOutline={
afterOutline
}
/* Top of the entire page */
top={
top
}
/* Bottom of the entire page */
bottom={
bottom
}
/* Custom MDX components */
components={{ p: (props) => }}
/>
);
export { Layout };
// re-export
export * from '@rspress/core/theme';
```
### 3. Custom home page and 404 page
In addition to the slot method, if you want to extend the default theme components, you can also customize the Home page components and 404 page components,
as well as other Rspress [built-in components](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/components)
```tsx title="theme/index.tsx"
import {
Search as BasicSearch,
Layout as BasicLayout,
} from '@rspress/core/theme';
// Custom Home Page
const HomeLayout = () =>
);
export { Search, HomeLayout, NotFoundLayout };
// re-export
export * from '@rspress/core/theme';
```
Of course, you may need to use page data during the development process, you can get it through [`Runtime API`](/api/client-api/api-runtime).
### 4. Custom icon
If you want to modify the icons used in the default theme component individually, just put the icons with the same name in the theme/assets directory.
```txt
└── theme
└── assets
└── logo.svg
```
You can view all the icons used in the default theme [here](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/assets).
## Redevelop a custom theme
If you're developing a custom theme from scratch, you need to understand the basic structure of the theme and the runtime API.
### 1. Basic structure
By default, you need to create a `theme` directory under the project root directory, and then create an `index.ts` or `index.tsx` file under the `theme` directory, which is used to export the theme content.
```txt
├── theme
│ └── index.tsx
```
In the `theme/index.tsx` file, you need to export a Layout component, which is the entry component of your theme:
```tsx
// theme/index.tsx
function Layout() {
return
Custom Theme Layout
;
}
// The setup function will be called when the page is initialized. It is generally used to monitor global events, and it can be an empty function
const setup = () => {};
// Export Layout component and setup function
export { Layout, setup };
// Export all content of the default theme to ensure that your theme configuration can work properly
export * from '@rspress/core/theme';
```
Layout component will be used to render the layout of the entire document site, you can introduce your custom components in this component, for example:
```tsx
// theme/index.tsx
import { Navbar } from './Navbar';
function Layout() {
return (
;
}
```
So the question is, how does the theme component get the page data and the content of the body MDX component? Next, let's take a look at the related APIs.
### 2. Runtime API
#### usePageData
Get information about all data on the site, such as:
```tsx
import { usePageData } from '@rspress/core/runtime';
function MyComponent() {
const pageData = usePageData();
return
{pageData.title}
;
}
```
#### useLang
Get the current language information, such as:
```tsx
import { useLang } from '@rspress/core/runtime';
function MyComponent() {
const lang = useLang();
return
{lang}
;
}
```
#### Content
Get MDX component content, such as:
```tsx
import { Content } from '@rspress/core/runtime';
function Layout() {
return (
);
}
```
#### Route hook
[react-router-dom](https://reactrouter.com/) is used inside Rspress to implement routing, so you can directly use the Hook of `react-router-dom`, for example:
```tsx
import { useLocation } from '@rspress/core/runtime';
function Layout() {
const location = useLocation();
return
Current location: {location.pathname}
;
}
```
### 3. Reusing search functionality
The default theme comes with built-in search functionality, which we can break down into two components:
1. The search box, i.e., the entry point to invoke the search.
2. The search panel that pops up after clicking on the search box.
#### Full reuse
If you want to fully reuse the search functionality, you can directly import the `Search` component, like so:
```tsx
import { Search } from '@rspress/core/theme';
function MySearch() {
return ;
}
```
#### Reusing the search panel
If you only want to reuse the search panel and customize the search box part, then you need to import the `SearchPanel` component in your theme component, like so:
```tsx
import { useState } from 'react';
import { SearchPanel } from '@rspress/core/theme';
function MySearch() {
const [focused, setFocused] = useState(false);
return (
);
}
```
In this case, you need to maintain the `focused` state and `setFocused` method yourself, and pass them as props to the `SearchPanel` component for controlling the display and hiding of the search panel.
#### Reuse default full text search logic
If you want to reuse the default full text search logic, you can use the `useFullTextSearch` Hook, for example:
```tsx
import { useFullTextSearch } from '@rspress/core/theme';
function MySearch() {
const { initialized, search } = useFullTextSearch();
useEffect(() => {
async function searchSomeKeywords(keywords: string) {
if (initialized) {
// Search for keywords
const results = await search(keywords);
console.log(results);
}
}
searchSomeKeywords('keyword');
}, [initialized]);
return
Search
;
}
```
Here, `initialized` indicates whether the search is initialized, the `search` method is used to search for keywords, returning a Promise, the result of the Promise is the result of the default full text search.
It should be noted that the `useFullTextSearch` Hook will automatically load the search index during initialization, so you need to first determine the `initialized` status, ensure that initialization is complete, and then call the `search` method.
The type definition of the search method is as follows:
```ts
type SearchFn = (keywords: string, limit?: number) => Promise;
```
The limit represents the maximum number of search results, default is 7, which means by default it returns a maximum of seven article results.
---
url: /api/index.md
---
---
url: /api/config/config-basic.md
---
# Basic config
## root
- **Type**: `string`
- **Default**: `docs`
Specifies the document root directory. For example:
```ts title="rspress.config.ts" twoslash
import { defineConfig } from '@rspress/core';
export default defineConfig({
root: 'docs',
});
```
This config supports both relative and absolute paths, with relative paths being relative to the current working directory(cwd).
Of course, in addition to specifying the document root directory through the config file, you can also specify it through command line parameters, such as:
```bash
rspress dev docs
rspress build docs
```
## base
- **Type**: `string`
- **Default**: `/`
Deployment base path. For example, if you plan to deploy your site to `https://foo.github.io/bar/`, then you should set `base` to `"/bar/"`:
```ts title="rspress.config.ts" twoslash
import { defineConfig } from '@rspress/core';
export default defineConfig({
base: '/bar/',
});
```
## title
- **Type**: `string`
- **Default**: `"Rspress"`
Site title. This parameter will be used as the title of the HTML page. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
title: 'My Site',
});
```
## description
- **Type**: `string`
- **Default**: `""`
Site description. This will be used as the description of the HTML page. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
description: 'My Site Description',
});
```
## icon
- **Type**: `string | URL`
- **Default**: `""`
Site icon. This path will be used as the icon path for the HTML page. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
icon: '/favicon.ico',
});
```
For normal path, Rspress will find your icon in the `public` directory, of course you can also set it to a CDN address, or use the `file://` protocol or `URL` to use local absolute path.
## lang
- **Type**: `string`
- **Default**: `""`
Default language of the site. See [Internationalization](/guide/default-theme/i18n) for more details.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
lang: 'en',
locales: [
{
lang: 'en',
// ...
},
{
lang: 'zh',
// ...
},
],
});
```
## logo \{#logo-1}
- **Type**: `string | { dark: string; light: string }`
- **Default**: `""`
Site logo. This path will be used as the logo path in the upper left corner of the navbar. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
logo: '/logo.png',
});
```
Rspress will find your icon in the `public` directory, you can also set it to a CDN address.
Of course you can set different logos for dark/light mode:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
logo: {
dark: '/logo-dark.png',
light: '/logo-light.png',
},
});
```
## logoText
- **Type**: `string`
- **Default**: `""`
Site logo Text. This text will be used as the logo text in the upper left corner of the navbar. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
logoText: 'rspress',
});
```
## outDir
- **Type**: `string`
- **Default**: `doc_build`
Custom output directory for built sites. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
outDir: 'doc_build',
});
```
## locales
- **Type**: `Locale[]`
```ts
export interface Locale {
lang: string;
label: string;
title?: string;
description?: string;
}
```
I18n config of the site. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
locales: [
{
lang: 'en-US',
label: 'English',
title: 'My Site',
description: 'My site description',
},
{
lang: 'zh-CN',
label: '简体中文',
title: '站点标题',
description: '站点描述',
},
],
});
```
## head
- **Type**: `string` | `[string, Record]` | `(route) => string | [string, Record] | undefined`
- Can be appended per page via [frontmatter](./config-frontmatter.mdx#head)
Used to set additional elements rendered in the `` tag of the page's HTML in production mode.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
// ... other user config
head: [
'',
// or
['meta', { name: 'author', content: 'John Doe' }],
// [htmlTag, { attrName: attrValue, attrName2: attrValue2 }]
// or
(route) => {
if (route.routePath.startsWith('/jane/')) return "";
if (route.routePath.startsWith('/john/')) return ['meta', { name: 'author', content: 'John Doe' }];
\\ or even skip returning anything
return undefined;
}
]
});
```
## mediumZoom
- **Type**: `boolean` | `{ selector?: string }`
- **Default**: `true`
Whether to enable the image zoom function. It is enabled by default, you can disable it by setting `mediumZoom` to `false`.
> The bottom layer is implemented using the [medium-zoom](https://github.com/francoischalifour/medium-zoom) library.
Example usage:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
// Turn off image zoom
mediumZoom: false,
// Configure the CSS selector to customize the picture to be zoomed, the default is '.rspress-doc img'
mediumZoom: {
selector: '.rspress-doc img',
},
});
```
## search
- **Type**:
```ts
type SearchOptions = {
searchHooks?: string;
versioned?: boolean;
codeBlocks?: boolean;
};
```
### searchHooks
- **Type**: `string`
- **Default**: `undefined`
You can add search runtime hooks logic through the `searchHooks` parameter, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
search: {
searchHooks: path.join(__dirname, 'searchHooks.ts'),
},
});
```
For specific hook logic, you can read [Customize Search Functions](/guide/advanced/custom-search).
### versioned
- **Type**: `boolean`
- **Default**: `false`
If you are using `multiVersion`, the `versioned` parameter allows you to create a separate search index for each version of your documentation.
When enabled, the search will only query the index corresponding to the currently selected version.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
search: {
versioned: true,
},
});
```
### codeBlocks
- **Type**: `boolean`
- **Default**: `true`
Whether to include code block content in the search index, which allows users to search code blocks.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
search: {
codeBlocks: false,
},
});
```
## globalUIComponents
- **Type**: `(string | [string, object])[]`
- **Default**: `[]`
You can register global UI components through the `globalUIComponents` parameter, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
globalUIComponents: [path.join(__dirname, 'components', 'MyComponent.tsx')],
});
```
The item of `globalUIComponents` can be a string, which is the path of the component file, or an array, the first item is the path of the component file, and the second item is the component props, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
globalUIComponents: [
[
path.join(__dirname, 'components', 'MyComponent.tsx'),
{
foo: 'bar',
},
],
],
});
```
When you register global components, Rspress will automatically render these React components in the theme without manually importing and using them.
Through global components, you can complete many custom functions, such as:
```tsx title="compUi.tsx"
import React from 'react';
// Need a default export
// The props comes from your config
export default function PluginUI(props?: { foo: string }) {
return
This is a global layout component
;
}
```
In this way, the content of the component will be rendered in the theme page, such as adding **BackToTop** button.
In the meanwhile, you can also use the global component to register some side effects, such as:
```tsx title="compSideEffect.tsx"
import { useEffect } from 'react';
import { useLocation } from '@rspress/core/runtime';
// Need a default export
export default function PluginSideEffect() {
const { pathname } = useLocation();
useEffect(() => {
// Executed when the component renders for the first time
}, []);
useEffect(() => {
// Executed when the route changes
}, [pathname]);
return null;
}
```
This way, side effects of components are executed in the theme page. For example, some of the following scenarios require side effects:
- Redirect for certain page routes.
- Bind click event on the img tag of the page to implement the image zoom function.
- When the route changes, the PV data of different pages are reported.
- ......
## multiVersion
- **Type**: `{ default: string; versions: string[] }`
You can enable multi-version support through the `multiVersion` parameter, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
multiVersion: {
default: 'v1',
versions: ['v1', 'v2'],
},
});
```
The `default` parameter is the default version, and the `versions` parameter is the version list.
## route
- **Type**: `Object`
Custom route config.
### route.include
- **Type**: `string[]`
- **Default**: `[]`
Add some extra files in the route. By default, only the files in the document root directory will be included in the route. If you want to add some extra files to the route, you can use this option. For example:
```js
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
include: ['other-dir/**/*.{md,mdx}'],
},
});
```
> Note: The strings in the array support glob patterns, the glob expression should be based on the `root` directory of the document, with the corresponding extensions suffix.
:::note
We recommend using [addPages hook](/plugin/system/plugin-api.html#addpages) in a custom Rspress plugin to add some additional files to the route, so that the page route and file path/content can be specified more flexibly and reasonably.
:::
### route.exclude
- **Type**: `string[]`
- **Default**: `[]`
Exclude some files from the route. For example:
```js
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
exclude: ['custom.tsx', 'component/**/*'],
},
});
```
> Note: The strings in the array support glob patterns, the glob expression should be based on the `root` directory of the document.
### route.excludeConvention
- **Type**: `string[]`
- **Default**: `['**/_[^_]*']`
A [routing convention](../../guide/use-mdx/components.mdx) set for the convenience of users to use components in the [docs directory](/api/config/config-basic#root), which excludes files starting with `_` by default.
If you really need some routes starting with `_`, you can adjust this rule, for example, set it to exclude only files starting with `_fragment-`:
```js title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
excludeConvention: ['**/_fragment-*'],
},
});
```
### route.extensions
- **Type**: `string[]`
- **Default**: `['.js', '.jsx', '.ts', '.tsx', '.md', '.mdx']`
The extensions of the files that will be included in the route. By default, Rspress will include all `'js'`, `'jsx'`, `'ts'`, `'tsx'`, `'md'`, `'mdx'` files in the route. If you want to customize the extensions, you can use this option. For example:
```js
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
extensions: ['.md', '.mdx'],
},
});
```
### route.cleanUrls
- **Type**: `Boolean`
- **Default**: `false`
Generate url without suffix when `cleanUrls` is `true` for shorter url link.
```js
import { defineConfig } from '@rspress/core';
export default defineConfig({
route: {
cleanUrls: true,
},
});
```
## ssg
- **Type**: `boolean | { experimentalWorker?: boolean; experimentalLoose?: boolean; }`
- **Default**: `true`
Whether to enable static site generation. Rspress enable it by default to generate CSR outputs and SSG outputs.
If your document site is only required to be used in CSR scenarios, you can set `ssg` to `false`, and Rspress will only generate CSR outputs.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
ssg: false,
});
```
:::tips
SSG requires the source code to support SSR. If the code is not compatible to SSR, the build process will fail. You can try:
1. Fix code to make it SSR-compatible.
2. Set `ssg: false`, but the SSG feature will be lost.
:::
### experimentalWorker
- **Type**: `boolean`
- **Default**: `false`
After enabled, you can use worker to accelerate the SSG process and reduce memory usage. It is suitable for large document sites and is based on [tinypool](https://github.com/tinylibs/tinypool).
### experimentalExcludeRoutePaths
- **Type**: `(string | RegExp)[]`
- **Default**: `[]`
After enabled, some pages will not be rendered by SSG, and they will directly use html under CSR. This is suitable for SSG errors in large document sites bypassing a small number of pages. It is not recommended to enable this option actively.
## replaceRules
- **Type**: `{ search: string | RegExp; replace: string; }[]`
- **Default**: `[]`
You can set text replacement rules for the entire site through `replaceRules`. The rules will apply to everything including `_meta.json` files, frontmatter configurations, and document content and titles.
```ts title="rspress.config.ts"
export default {
replaceRules: [
{
search: /foo/g,
replace: 'bar',
},
],
};
```
## languageParity
- **Type**: `Object`
Scans the `md` and `mdx` files in the document root directory to detect missing language versions, protect language parity.
### languageParity.enable
- **Type**: `boolean`
- **Default**: `false`
Whether to enable language parity checks.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
languageParity: {
enabled: true,
},
});
```
### languageParity.include
- **Type**: `string[]`
- **Default**: `[]`
Specifies the folders to be checked, defaulting to all files in the document root directory. Paths should be relative to each language directory. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
languageParity: {
// `posts/foods` and `articles` folders under the zh/en language directories
include: ['posts/foods', 'articles'],
},
});
```
### languageParity.exclude
- **Type**: `string[]`
- **Default**: `[]`
Excludes certain folders and files from the checks.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
languageParity: {
exclude: ['excluded-directory', 'articles/secret.md'],
},
});
```
---
url: /api/config/config-theme.md
---
# Theme config
Theme config is located under `themeConfig` in the `doc` param. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
// ...
},
});
```
## nav
- Type: `Array`
- Default: `[]`
The `nav` configuration is an array of `NavItem` with the following types:
```ts
interface NavItem {
// Navbar text
text: string;
// Navbar link
link: '/';
// Activation rules for navbar links
activeMatch: '^/$|^/';
// svg tag string or image URL(optional)
tag?: string;
}
```
`activeMatch` is used to match the current route, when the route matches the `activeMatch` rule, the nav item will be highlighted. By default, `activeMatch` is the `link` of the nav item.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
nav: [
{
text: 'Home',
link: '/',
},
{
text: 'Guide',
link: '/guide/',
},
],
},
});
```
Of course, multi-level menus can also be configured in the `nav` array with the following types:
```ts
interface NavGroup {
text: string;
// submenu
items: NavItem[];
// svg tag string or image URL(optional)
tag?: string;
}
```
For example the following configuration:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
nav: [
{
text: 'Home',
link: '/',
},
{
text: 'Guide',
items: [
{
text: 'Getting Started',
link: '/guide/getting-started',
},
{
text: 'Advanced',
link: '/guide/advanced',
},
// Also support sub group menu
{
text: 'Group',
items: [
{
text: 'Personal',
link: 'http://example.com/',
},
{
text: 'Company',
link: 'http://example.com/',
},
],
},
],
},
],
},
});
```
## sidebar
- Type: `Object`
The sidebar of the website. The config is an object with the following types:
```ts
// The key is the path of SidebarGroup
// value is an array of SidebarGroup
type Sidebar = Record;
interface SidebarGroup {
text: string;
link?: string;
items: SidebarItem[];
// whether to be collapsible
collapsible?: boolean;
// Whether to be collapsed by default
collapsed?: boolean;
// svg tag string or image URL(optional)
tag?: string;
}
// An object can be filled in, or a string can be filled in
// When filling in a string, it will be converted into an object internally, the string will be used as a link, and the text value will automatically take the title of the corresponding document
type SidebarItem =
| {
// sidebar text
text: string;
// sidebar link
link: string;
// svg tag string or image URL(optional)
tag?: string;
}
| string;
```
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
sidebar: {
'/guide/': [
{
text: 'Getting Started',
items: [
// Fill in an object
{
text: 'Introduction',
link: '/guide/getting-started/introduction',
},
{
text: 'Installation',
link: '/guide/getting-started/installation',
},
],
},
{
text: 'Advanced',
items: [
// Fill in the link string directly
'/guide/advanced/customization',
'/guide/advanced/markdown',
],
},
],
},
},
});
```
## footer
- Type: `Object`
- Default: `{}`
The footer of the home page.
The `footer` config is an object of `Footer`, which has the following types:
```ts
export interface Footer {
message?: string;
copyright?: string;
}
```
`message` is a string that can contain HTML content. This string will be inserted into the footer using `dangerouslySetInnerHTML`, allowing you to pass in HTML template tags to design your footer.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
footer: {
message:
'
',
},
},
});
```
## outline
- Type: `boolean`
- Default: `true`
Whether to show the sidebar in right position.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
outline: false,
},
});
```
## outlineTitle
- Type: `string`
- Default: 'ON THIS PAGE'
Configure the title of the outline in the outline panel.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
outlineTitle: 'Outline',
},
});
```
## lastUpdated
- Type: `boolean`
- Default: `false`
Whether to display the last update time, it is not displayed by default.
:::info
You need to commit the markdown file to see the updated time.
:::
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
lastUpdated: true,
},
});
```
## lastUpdatedText
- Type: `string`
- Default: `Last Updated`
The text of the last update time.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
lastUpdatedText: 'Last Updated',
},
});
```
## prevPageText
- Type: `string`
- Default: `Previous Page`
The text of the previous page. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
prevPageText: 'Previous Page',
},
});
```
## searchPlaceholderText
- Type: `string`
- Default: `Search`
The placeholder text of the search box. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
searchPlaceholderText: 'Search',
},
});
```
## searchNoResultsText
- Type: `string`
- Default: `No results for`
The text of no search result. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
searchNoResultsText: 'No results for',
},
});
```
## searchSuggestedQueryText
- Type: `string`
- Default: `Please try again with a different keyword`
The text of suggested query text when no search result. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
searchSuggestedQueryText: 'Please search again',
},
});
```
## overview
- Type: `Object`
The config of overview page/component. The config is an object with the following types:
```ts
interface FilterConfig {
filterNameText?: string;
filterPlaceholderText?: string;
filterNoResultText?: string;
}
```
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
overview: {
filterNameText: 'Filter',
filterPlaceholderText: 'Enter keyword',
filterNoResultText: 'No matching API found',
},
},
});
```
## socialLinks
- Type: `Array`
- Default: `[]`
You can add related links through the following config, such as `github` links, `x` links, etc.
Related links support four modes: `link mode` `text mode` `image mode` `dom mode`, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
socialLinks: [
{
icon: 'github',
mode: 'link',
content: 'https://github.com/sanyuan0704/island.js',
},
{
icon: 'wechat',
mode: 'text',
content: 'wechat: foo',
},
{
icon: 'qq',
mode: 'img',
content: '/qrcode.png',
},
{
icon: 'github',
mode: 'dom',
content:
'',
},
],
},
});
```
- When in `link` mode, click the icon to jump to the link.
- When in `text` mode, when the mouse moves over the icon, a pop-up box will be displayed, and the content of the pop-up box is the entered text
- When in the `img` mode, moving the mouse over the icon will display a bullet box, and the content of the bullet box is the specified picture. It should be noted that the picture needs to be placed in the `public` directory.
- When in dom mode, html to render can be passed directly into the content field. Use '' for wrapping
Related links support the following types of images, which can be selected through the icon attribute:
```ts
export type SocialLinkIcon =
| 'lark'
| 'discord'
| 'facebook'
| 'github'
| 'instagram'
| 'linkedin'
| 'slack'
| 'x'
| 'youtube'
| 'wechat'
| 'qq'
| 'juejin'
| 'zhihu'
| 'bilibili'
| 'weibo'
| 'gitlab'
| 'X'
| 'bluesky'
| 'npm'
| { svg: string };
```
If you need to customize the icon, you can pass in an object with `svg attribute`, and the value of svg is the content of the custom icon, for example:
```js
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
socialLinks: [
{
icon: {
svg: '',
},
mode: 'link',
content: 'https://github.com/',
},
],
},
});
```
## nextPageText
- Type: `string`
- Default: `Next Page`
Text for the next page. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
nextPageText: 'Next Page',
},
});
```
## locales
- Type: `Array`
- Default: `undefined`
I18n config. This config is an array, and every item of it is `LocaleConfig`, and the types are as follows:
```ts
export interface LocaleConfig {
/**
* General locale config for site, which will have a higher priority than `locales`
*/
// language name
lang?: string;
// HTML title, takes precedence over `themeConfig.title
title?: string;
// HTML description, takes precedence over `themeConfig.description`
description?: string;
// Display text for the corresponding language
label: string;
/**
* Locale config for theme.
*/
// Right outline title
outlineTitle?: string;
// Whether to display the last update time
lastUpdated?: boolean;
// Last update time text
lastUpdatedText?: string;
// Previous text
prevPageText?: string;
// Next page text
nextPageText?: string;
// Search box placeholder text
searchPlaceholderText?: string;
// The text of no search result
searchNoResultsText?: string;
// The text of suggested query text when no search result
searchSuggestedQueryText?: string;
// Info for the edit link.
editLink?: EditLink;
}
```
`LocaleConfig` contains many of the same configuration options as the theme config, but the former will have a higher priority.
## darkMode
- Type: `boolean`
- Default: `true`
Whether a Dark/Light mode toggle button appears. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
darkMode: true,
},
});
```
You can also specify the default theme mode through inject global variable into html template, for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
builderConfig: {
html: {
tags: [
{
tag: 'script',
// Specify the default theme mode, which can be `dark` or `light`
children: "window.RSPRESS_THEME = 'dark';",
},
],
},
},
});
```
## hideNavbar
- Type: `"always" | "auto" | "never"`
- Default: `never`
Control the behavior of the hidden navigation bar. By default, the navigation bar will always display. You can set it to `auto` to **automatically hide when the page scrolls down**, or set it to `always` to hidden it all the time.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
hideNavbar: 'auto',
},
});
```
## editLink
- Type:
```ts
interface EditLink {
/**
* Custom repository url for edit link.
*/
docRepoBaseUrl: string;
/**
* Custom text for edit link.
*
* @default 'Edit this page'
*/
text?: string;
}
```
- Default: `undefined`
Display a link to edit the page on Git management services such as GitHub, or GitLab.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
editLink: {
docRepoBaseUrl:
'https://github.com/web-infra-dev/rspress/tree/main/website/docs',
text: '📝 Edit this page on GitHub',
},
},
});
```
## enableContentAnimation
- Type: `boolean`
- Default: `false`
Whether there is animation effect when switching between pages. It is implemented with [View Transition API](https://developer.mozilla.org/docs/Web/API/View_Transitions_API). For example:
> The animation is not configurable for now.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
enableContentAnimation: true,
},
});
```
## enableAppearanceAnimation
- Type: `boolean`
- Default: `false`
Whether there is animation effect when switching between light and dark theme. It is implemented with [View Transition API](https://developer.mozilla.org/docs/Web/API/View_Transitions_API). For example:
> The animation is not configurable for now.
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
enableAppearanceAnimation: true,
},
});
```
## search
- Type: `boolean`
- Default: `true`
Whether to display the search box. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
search: false,
},
});
```
## sourceCodeText
- Type: `string`
- Default: `Source`
The text of the source code button. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
sourceCodeText: 'Source',
},
});
```
## enableScrollToTop
- Type: `boolean`
- Default: `false`
Enable scroll to top button on documentation. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
enableScrollToTop: true,
},
});
```
## localeRedirect
- Type: `'auto' | 'never' | 'only-default-lang'`
- Default: `'auto'`
Whether to redirect to the locale closest to `window.navigator.language` when the user visits the site, the default is `auto`, which means that the user will be redirected on the first visit. If you set it to `never`, the user will not be redirected. If you set it to `only-default-lang`, the user will only be redirected when visiting the default locale. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
localeRedirect: 'never',
},
});
```
## fallbackHeadingTitle
- Type: `boolean`
- Default: `true`
Whether to display [`frontmatter.title`](./config-frontmatter#title) as fallback when the heading title is not presented. For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
themeConfig: {
fallbackHeadingTitle: false,
},
});
```
---
url: /api/config/config-frontmatter.md
---
# Front matter config
This document introduces how to configure various properties of a page using front matter, including title, description, page type, navbar, etc.
See [Front matter](/guide/use-mdx.html#front-matter) for what front matter is and how to use it.
## title
- Type: `string`
The title of the page. By default, the page's h1 heading will be used as the title of the HTML document. But if you want to use a different title, you can use front matter to specify the title of the page. For example:
```yaml
---
title: My Home Page
---
```
## description
- Type: `string`
A custom description for the page. For example:
```yaml
---
description: This is my custom description for this page.
---
```
## pageType
- Type: `'home' | 'doc' | 'custom' | 'blank' | '404'`
- Default: `'doc'`
The type of the page. By default, the page type is `doc`. But if you want to use a different page type, you can use the front matter field `pageType` to specify the page type. E.g:
```yaml
---
pageType: home
---
```
The meaning of each `pageType` config is as follows:
import PageType from '@en/fragments/page-type';
## titleSuffix
- Type: `string`
Set the suffix of the page title. When `titleSuffix` is not set, the site's [title](/api/config/config-basic#title) is used as the suffix by default.
```yaml
---
titleSuffix: 'Rsbuild-based Static Site Generator'
---
```
The default separator between the title and the suffix is `-`, you can also use `|` for separation:
```yaml
---
titleSuffix: '| Rsbuild-based Static Site Generator'
---
```
## head
- Type: `[string, Record][]`
Specify extra head tags to be injected for the current page. Will be appended after head tags injected by site-level config.
For example, you can use these headers to specify custom meta tags for [Open Graph](https://ogp.me/).
```yaml
---
head:
- - meta
- property: og:url
content: https://example.com/foo/
- - meta
- property: og:image
content: https://example.com/bar.jpg
# - - [htmlTag]
# - [attributeName]: [attributeValue]
# [attributeName]: [attributeValue]
---
```
The generated head tags are as follows:
```html
```
## hero
- Type: `Object`
The hero config for the home page. It has the following types:
```ts
interface Hero {
name: string;
text: string;
tagline: string;
image?: {
src: string | { dark: string; light: string };
alt: string;
/**
* `srcset` and `sizes` are attributes of `` tag. Please refer to https://mdn.io/srcset for the usage.
* When the value is an array, rspress will join array members with commas.
**/
srcset?: string | string[];
sizes?: string | string[];
};
actions: {
text: string;
link: string;
theme: 'brand' | 'alt';
}[];
}
```
For example, you can use the following front matter to specify a page's hero config:
```yaml
---
pageType: home
hero:
name: Rspress
text: A Documentation Solution
tagline: A modern documentation development technology stack
actions:
- theme: brand
text: Introduction
link: /en/guide/introduction
- theme: alt
text: Quick Start
link: /en/guide/getting-started
---
```
When setting `hero.text`, you can use the `|` symbol in YAML to manually control line breaks:
```yaml
---
pageType: home
hero:
name: Rspress
text: |
A Documentation
Solution
```
Or you can use `HTML` to specify the hero config for the page:
```yaml
---
pageType: home
hero:
name: Rspress
text: A Documentation Solution
tagline: A modern documentation development technology stack
actions:
- theme: brand
text: Introduction
link: /zh/guide/introduction
- theme: alt
text: Quick Start
link: /zh/guide/getting-started
---
```
## features
- Type: `Array`
- Default: `[]`
features config of the `home` page. It has the following types:
```ts
interface Feature {
title: string;
details: string;
icon: string;
// The length of the card grid, currently only support[3, 4, 6]
span?: number;
// The link of the feature, not required.
link?: string;
}
export type Features = Feature[];
```
For example, you could use the following to specify the features configuration for the `home` page:
```yaml
---
pageType: home
features:
- title: 'MDX Support'
details: MDX is a powerful way to write content. You can use React components in Markdown.
icon: 📦
- title: 'Feature Rich'
details: Out of box support for i18n, full-text search etc.
icon: 🎨
- title: 'Customizable'
details: You can customize the theme ui and the build process.
icon: 🚀
---
```
## sidebar
Whether to show the sidebar on the left. By default, the `doc` page will display the sidebar on the left. If you want to hide the sidebar on the left, you can use the following front matter config:
```yaml
---
sidebar: false
---
```
## outline
Whether to display the outline column on the right. By default, the `doc` page displays the outline column on the right. You can hide the outline column with the following config:
```yaml
---
outline: false
---
```
## footer
Whether to display the components at the bottom of the document (such as previous/next page). By default, the `doc` page will display the footer at the bottom. You can hide the footer with the following config:
```yaml
---
footer: false
---
```
## navbar
Whether to hide the top navigation bar. You can hide the top nav bar with the following config:
```yaml
---
navbar: true
---
```
## overviewHeaders
- Type: `number[]`
- Default: `[2]`
The headers shown in the overview page. By default, the displayed header is h2. But if you want to display different headers, you can specify it using the `overviewHeaders` front matter field. For example:
```yaml
---
overviewHeaders: []
---
```
Or
```yaml
---
overviewHeaders: [2, 3]
---
```
## context
- Type: `string`
After configuration, the `data-context` attribute will be added to the DOM node when the sidebar is generated, and the value is the configured value.
```yaml title="foo.mdx"
---
context: 'context-foo'
---
```
```yaml title="bar.mdx"
---
context: 'context-bar'
---
```
The DOM structure of the final generated sidebar is abbreviated as follows:
```html
```
---
url: /api/config/config-build.md
---
# Build config
## builderConfig
- **Type**: `RsbuildConfig`
Used to customize the configurations of Rsbuild. For detailed configurations, please refer to [Rsbuild - Config](https://rsbuild.rs/config/).
- Example: Use [resolve.alias](https://rsbuild.rs/config/resolve/alias) to configure path aliases:
```ts title="rspress.config.ts"
export default defineConfig({
builderConfig: {
resolve: {
alias: {
'@common': './src/common',
},
},
},
});
```
- Example: Use [tools.rspack](https://rsbuild.rs/config/tools/rspack) to modify the Rspack configuration, such as registering a webpack or Rspack plugin:
```ts title="rspress.config.ts"
export default defineConfig({
builderConfig: {
tools: {
rspack: async (config) => {
const { default: ESLintPlugin } = await import('eslint-webpack-plugin');
config.plugins?.push(new ESLintPlugin());
return config;
},
},
},
});
```
::: warning
If you want to modify the output directory, please use [outDir](/api/config/config-basic#outdir).
:::
## builderConfig.plugins
- **Type**: `RsbuildPlugin[]`
To register [Rsbuild plugins](https://rsbuild.rs/plugins/list/).
You can leverage Rsbuild's extensive plugin ecosystem to enhance and extend your build capabilities.
- Example: Support Vue SFC through [@rsbuild/plugin-vue](https://rsbuild.rs/plugins/list/plugin-vue)
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginVue } from '@rsbuild/plugin-vue';
export default defineConfig({
builderConfig: {
plugins: [pluginVue()],
},
});
```
- Example: Add Google analytics through [rsbuild-plugin-google-analytics](https://github.com/rspack-contrib/rsbuild-plugin-google-analytics).
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginGoogleAnalytics } from 'rsbuild-plugin-google-analytics';
export default defineConfig({
builderConfig: {
plugins: [
pluginGoogleAnalytics({
// replace this with your Google tag ID
id: 'G-xxxxxxxxxx',
}),
],
},
});
```
- Example: Add Open Graph meta tags through [rsbuild-plugin-open-graph](https://github.com/rspack-contrib/rsbuild-plugin-open-graph).
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginOpenGraph } from 'rsbuild-plugin-open-graph';
export default defineConfig({
builderConfig: {
plugins: [
pluginOpenGraph({
title: 'My Website',
type: 'website',
// ...options
}),
],
},
});
```
You can also override the built-in plugin [@rsbuild/plugin-react](https://rsbuild.rs/plugins/list/plugin-react) and customize the plugin options.
For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import { pluginReact } from '@rsbuild/plugin-react';
export default defineConfig({
builderConfig: {
plugins: [
pluginReact({
// ...options
}),
],
},
});
```
### Default config
If you need to view the default Rspack or Rsbuild configs, you can add the `DEBUG=rsbuild` parameter when running the `rspress dev` or `rspress build` command:
```bash
DEBUG=rsbuild rspress dev
```
After execution, the `rsbuild.config.js` file is created in the `doc_build` directory, which contains the complete `builderConfig`.
> Please refer to [Rsbuild - Debug Mode](https://rsbuild.rs/guide/debug/debug-mode) for more information on how to debug the Rsbuild.
## markdown
Configure MDX-related compilation abilities.
### markdown.remarkPlugins
- **Type**: `Array`
- Default: `[]`
Configure the remark plugins. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
remarkPlugins: [
[
require('remark-autolink-headings'),
{
behavior: 'wrap',
},
],
],
},
});
```
### markdown.rehypePlugins
- **Type**: `Array`
Configure the rehype plugin. for example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
rehypePlugins: [
[
require('rehype-autolink-headings'),
{
behavior: 'wrap',
},
],
],
},
});
```
### markdown.shiki
- **Type**: `import('@shikijs/rehype').RehypeShikiOptions`
- **Default**:
```ts
const cssVariablesTheme = createCssVariablesTheme({
name: 'css-variables',
variablePrefix: '--shiki-',
variableDefaults: {},
fontStyle: true,
});
const shikiOptions = {
theme: cssVariablesTheme,
defaultLanguage: 'txt',
lazy: true,
langs: ['tsx', 'ts', 'js'],
addLanguageClass: true,
};
```
Configure Shiki-related options. For details, see [RehypeShikiOptions](https://github.com/shikijs/shiki/blob/main/packages/rehype/src/types.ts).
### markdown.link
- **Type**:
```ts
export type RemarkLinkOptions = {
checkDeadLinks?:
| boolean
| { excludes: string[] | ((url: string) => boolean) };
autoPrefix?: boolean;
};
```
- **Default**: `{ checkDeadLinks: true, autoPrefix: true }`
Configure link-related options.
#### markdown.link.checkDeadLinks
- **Type**: `boolean | { excludes: string[] | ((url: string) => boolean) }`
- **Default**: `true`
After enabling this configuration, Rspress will check the links in the document based on convention routing. If an inaccessible link occurs, the build will throw an error and exit.
If there is a misjudgment of links, you can ignore the error through the `excludes` configuration:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
export default defineConfig({
markdown: {
link: {
checkDeadLinks: {
excludes: ['/guide/getting-started', '/llms.txt'],
},
},
},
});
```
#### markdown.link.autoPrefix
- **Type**: `boolean`
- **Default**: `true`
After enabling this config, Rspress will automatically add prefixes to links in documents based on the conventional routing about [i18n](/guide/default-theme/i18n) and [Multi version](/guide/default-theme/multi-version).
If a user writes a link `[](/guide/getting-started)` in `docs/zh/guide/index.md`, Rspress will automatically convert it to `[](/zh/guide/getting-started)`.
### markdown.showLineNumbers
- **Type**: `boolean`
Whether to display the line number of the code block. Defaults to `false`.
### markdown.defaultWrapCode
- **Type**: `boolean`
Whether to enable long code line wrapping display by default. Defaults to `false`.
### markdown.globalComponents
- **Type**: `string[]`
Register component to the global scope, which will make it automatically available in every MDX file, without any import statements.For example:
```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';
import path from 'path';
export default defineConfig({
markdown: {
globalComponents: [path.join(__dirname, 'src/src/components/Alert.tsx')],
},
});
```
Then you can use the `Alert` component in any MDX file:
```mdx title="test.mdx"
This is a info alert
```
---
url: /api/client-api/api-runtime.md
---
# Runtime API
Rspress exposes some runtime APIs, which is convenient for you to do some custom logic.
## usePageData
- **Type:** `() => PageData`
Get the data of the current page, and the return value is an object, which contains all the data of the current page.
```js
import { usePageData } from '@rspress/core/runtime';
function MyComponent() {
const pageData = usePageData();
return
{pageData.page.title}
;
}
```
## useLang
- **Type:** `() => string`
Get the current language, the return value is a string, which is the current language.
```js
import { useLang } from '@rspress/core/runtime';
function MyComponent() {
const lang = useLang();
// lang === 'zh-CN'
return
{lang}
;
}
```
## useVersion
- **Type:** `() => string`
Get the current version, the return value is a string, which is the current version.
```tsx
import { useVersion } from '@rspress/core/runtime';
export default () => {
const version = useVersion();
return
Current version: {version}
;
};
```
## useDark
- **Type:** `() => boolean`
Whether it is dark mode currently, the return value is a boolean value.
```js
import { useDark } from '@rspress/core/runtime';
function MyComponent() {
const dark = useDark();
return
{dark}
;
}
```
Note that in the SSG process, `useDark` cannot accurately reflect the theme setting of the user's browser, because SSG is executed during the build stage. Only after client hydration is complete, this hook will return the correct theme value.
If you need to apply a dark theme style in the SSG stage, it is recommended to use the CSS selector `.dark` to set the style. Rspress will add the `dark` class name to the root element of the document, which will be effective in both SSG and client:
```css
/* Light mode style */
.my-component {
color: black;
background-color: white;
}
/* Dark mode style */
.dark .my-component {
color: white;
background-color: #1a1a1a;
}
```
## useI18n
Rspress provides `useI18n` this hook to get the internationalized text, the usage is as follows:
```tsx
import { useI18n } from '@rspress/core/runtime';
const MyComponent = () => {
const t = useI18n();
return
{t('gettingStarted')}
;
};
```
For better type hinting, you can configure `paths` in tsconfig.json:
```json
{
"compilerOptions": {
"paths": {
"i18n": ["./i18n.json"]
}
}
}
```
Then use it like this in the component:
```tsx
import { useI18n } from '@rspress/core/runtime';
const MyComponent = () => {
const t = useI18n();
return
{t('gettingStarted')}
;
};
```
This way you get type hints for all literal keys defined in `i18n.json`.
> See more in [Internationalization](/guide/default-theme/i18n).
## Router hook
Rspress internally uses and re-exports all APIs of `react-router-dom`, you can use it like this:
```ts
import { useLocation } from '@rspress/core/runtime';
function MyComponent() {
const location = useLocation();
return
{location.pathname}
;
}
```
---
url: /api/client-api/api-components.md
---
# Built-in components
:::info Note
In order to make it easier for you to use these components, the `rspress/theme` package has been aliased inside Rspress, so you can directly use `@theme` to import these components.
:::
## Badge
The Badge component is used to display a badge. For example:
```tsx title="index.mdx"
import { Badge } from '@theme';
function App() {
// Using text prop
return ;
// Using custom children
return (
Rspress
);
}
```
The effect is as follows:
import { Badge } from '@theme';
Custom children:
import SearchSvg from '@theme-assets/github';
RspressGithub
Inlined with text
##### H5
#### H4
### H3
The types of props included are as follows:
```ts
interface BadgeProps {
/**
* The content to display inside the badge. Can be a string or React nodes.
*/
children?: React.ReactNode;
/**
* The type of badge, which determines its color and style.
* @default 'tip'
*/
type?: 'tip' | 'info' | 'warning' | 'danger';
/**
* The text content to display inside the badge (for backwards compatibility).
*/
text?: string;
/**
* Whether to display the badge with an outline style.
* @default false
*/
outline?: boolean;
}
```
## Head
It is generally used to set custom head content in documents (based on [unhead](https://www.npmjs.com/package/unhead)). The usage is as follows:
```tsx title="index.tsx"
// Below is a custom component, you can import it into your document
import { Head } from '@rspress/core/runtime';
function App() {
return (
);
}
```
## HomeFeature
Feature component in Hero page, look [the effect in this website](/).
```tsx
import { HomeFeature } from '@rspress/core/theme';
interface Feature {
title: string;
details: string;
icon: string;
// only support [3, 4, 6]
span?: number;
link?: string;
}
export type Features = Feature[];
```
## HomeHero
Hero component in Hero page.
```tsx
import { HomeHero } from '@rspress/core/theme';
interface Hero {
name: string;
text: string;
tagline: string;
image?: {
src: string | { dark: string; light: string };
alt: string;
};
actions: {
text: string;
link: string;
theme: 'brand' | 'alt';
}[];
}
```
## LastUpdated
The LastUpdated component is used to display the last update time of the current page. For example:
```tsx title="index.mdx"
import { LastUpdated } from '@theme';
function App() {
return ;
}
```
:::tip
If `lastUpdated: true` is not configured in the default theme, you need to install and register the `@rspress/plugin-last-updated` plugin.
:::
## NoSSR
Used to skip the ssr for some components. For example:
```tsx
import { NoSSR } from '@rspress/core/runtime';
const Component = () => {
return (
The content here will only be rendered on the client side
);
};
```
## Overview
Overview component, look [the effect in this website](/api/)
```tsx
import { Overview } from '@rspress/core/theme';
interface GroupItem {
text?: string;
link?: string;
headers?: Header[];
}
interface Group {
name: string;
items: GroupItem[];
}
interface OverviewProps {
// content before data rendering
content?: React.ReactNode;
// data
groups?: Group[];
// default title
defaultGroupTitle?: string;
// headers displayed in the overview page of the file
overviewHeaders?: number[];
}
```
## PackageManagerTabs
The PackageManagerTabs component is used to display commands for different package managers in the documentation. The usage is as follows:
```tsx title="index.mdx"
import { PackageManagerTabs } from '@theme';
function App() {
return ;
}
```
The effect is as follows:
import { PackageManagerTabs } from '@theme';
The types of props included are as follows:
```ts
type PackageManagerTabProps = (
| {
command: string;
/**
* If true, the command will be interpreted as a shell command and prefixed with npx for npm,
* or the package manager binary for others.
*/
exec?: boolean;
}
| {
command: {
// Used to set commands for different package managers
npm?: string;
yarn?: string;
pnpm?: string;
bun?: string;
};
exec?: never;
}
) &
// Used to set additional tabs
{
additionalTabs?: {
// Used to set additional package managers
tool: string;
// Used to set the icon of the additional package manager
icon?: ReactNode;
}[];
};
```
When `command` is set to a string, it will default to displaying three tabs: npm, yarn, pnpm and bun, and the component will automatically add the corresponding package manager command before the command. If you need to display additional tabs, you can achieve this through `additionalTabs`.
For the `string` variant of the `command` prop, an optional `exec` prop can be used for presenting binary execution usage (by changing the NPM tab's command prefix to `npx`).
:::tip
In the install command, special processing has been done for yarn, pnpm and bun. If your command is `install some-packages`, the install will be automatically replaced with add in the yarn/pnpm/bun tab.
:::
## PrevNextPage
The PrevNextPage component is used to display the previous and next pages of the current page. For example:
```tsx title="index.mdx"
import { PrevNextPage } from '@theme';
function App() {
return (
);
}
```
The types of props included are as follows:
```ts
interface PrevNextPageProps {
// Set the link to the previous page or the next page through type
type: 'prev' | 'next';
// Used to set the text of the previous page or the next page
text: string;
// Used to set the link to the previous page or the next page
href: string;
}
```
## SourceCode
The SourceCode component is used to jump to the source code. For example:
```tsx title="index.mdx"
import { SourceCode } from '@theme';
function App() {
return (
);
}
```
The effect is as follows:
import { SourceCode } from '@theme';
The types of props included are as follows:
```ts
interface SourceCodeProps {
// Used to set the link to the source code
href: string;
// Used to set source platform
platform?: 'github' | 'gitlab';
}
```
## Steps
The Steps component is used to turn your content into a visual representation of steps.
```tsx title="index.mdx"
import { Steps } from '@theme';
function App() {
return (
### Step 1
Body for Step 1.
### Step 2
> Body for Step 2.
);
}
```
The effect is as follows:
import { Steps } from '@theme';
### Step 1
Body for Step 1.
### Step 2
> Body for Step 2.
## Tab/Tabs
You can use the `Tab` and `Tabs` component in the document to achieve the effect of tab switching. For example:
```mdx title="index.mdx"
import { Tab, Tabs } from '@rspress/core/theme';
Tab 1 contentTab 2 content
```
import { Tab, Tabs } from '@theme';
Tab 1 contentTab 2 content
### Code blocks
Using `Tabs` component to switch multiple code blocks.
````mdx title="index.mdx"
import { Tab, Tabs } from '@rspress/core/theme';
```tsx title="src/index.mjs"
import foo from 'foo';
import bar from 'bar';
```
```tsx title="src/index.cjs"
const foo = require('foo');
const bar = require('bar');
```
````
```tsx title="src/index.mjs"
import foo from 'foo';
import bar from 'bar';
```
```tsx title="src/index.cjs"
const foo = require('foo');
const bar = require('bar');
```
### Props
The props type of the Tabs component is as follows:
```ts
interface TabsProps {
children: React.ReactNode;
defaultValue?: string;
groupId?: string;
tabPosition?: 'left' | 'center';
}
```
- `defaultValue` is used to set the tab item selected by default. This value will be compared with the value field of the Tab component props, and if they are equal, the tab will be selected.
- `groupId` is used to sync the selected tab item between multiple Tabs components.The groups with the same groupId will be synchronized.
- `tabPosition` is used to set the position of the tab list, it has two values: `left` and `center`, the default is `left`.
The props types of the Tab component are as follows:
```ts
interface TabProps {
label: string;
// Used to identify the current tab, if not passed, the default label will be used
value?: string;
children: React.ReactNode;
}
```
The `value` field is used to identify the current tab, if not passed, the default label will be used.
## Table of contents
Render TOC of current page
```tsx title="index.mdx"
import { Toc } from '@theme';
function App() {
return ;
}
```
import { Toc } from '@theme';
## CodeBlockRuntime
Render code block in runtime
```tsx title="index.mdx"
import { CodeBlockRuntime } from '@theme';
function App() {
return (
);
}
```
import { CodeBlockRuntime } from '@theme';
---
url: /api/commands.md
---
# Commands
Through this chapter, you can learn about the built-in commands of Rspress and how to use them.
## rspress dev
The `rspress dev` command is used to start a local development server, providing a development environment for document preview and debugging.
```txt
Usage: rspress dev [root] [options]
Options:
root specify the root directory of the project, which is `docs` in current directory by default, Optional
-c --config specify config file path, which can be a relative path or an absolute path
--port specify port number
--host specify host
-h, --help show command help
```
## rspress build
The `rspress build` command is used to build documentation site for production.
```txt
Usage: rspress build [root] [options]
Options:
root specify the root directory of the project, which is `docs` in current directory by default, Optional
-c --config specify config file path, which can be a relative path or an absolute path
-h, --help show command help
```
## rspress preview
The `rspress preview` command is used to preview the output files of the `rspress build` command locally.
```txt
Usage: rspress preview [root] [options]
Options:
root specify the root directory of the project, which is `docs` in current directory by default, Optional
-c --config specify config file path, which can be a relative path or an absolute path
--port specify port number
--host specify host
-h, --help show command help
```
---
url: /index.md
---