close

Custom theme

  1. For CSS, Rspress provides CSS variables and BEM classnames for customization.

  2. For JS / React, Rspress implements a runtime interface based on ESM re-exports, supporting modification or replacement of built-in components to implement your own home page, sidebar, search components, etc.

    On top of this, there are two modes:

    • wrap: Wrap and enhance Rspress built-in components through props / slots.
    • eject: Directly override the entire component. You can use the rspress eject command to copy the source code locally and modify it directly.

The following will introduce them in order according to the degree of theme customization.

CSS variables

Rspress exposes some commonly used CSS variables. Compared to rewriting Rspress built-in React components, overriding CSS variables for customization is simpler and easier to maintain. You can view these CSS variables on the UI - CSS Variables page, and override them through:

theme/index.tsx
theme/index.css
import './index.css';
export * from '@rspress/core/theme-original';

BEM classname

Rspress built-in components all use BEM naming convention. You can use these classnames to override styles, in the same way as CSS Variables.

.rp-[component-name]__[element-name]--[modifier-name] {
  /* styles */
}

For example:

.rp-nav {
}
.rp-link {
}
.rp-tabs {
}
.rp-codeblock {
}
.rp-codeblock__title {
}
.rp-codeblock__description {
}
.rp-nav-menu__item,
.rp-nav-menu__item--active {
}

Override built-in components using ESM re-exports

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 components.

docs
theme
index.tsx
rspress.config.ts

You can write the theme/index.tsx file using built-in components from @rspress/core/theme-original:

theme/index.tsx
import { Layout as BasicLayout } from '@rspress/core/theme-original';

const Layout = () => <BasicLayout beforeNavTitle={<div>some content</div>} />;

export { Layout }; 
export * from '@rspress/core/theme-original'; 

By ESM re-export to override built-in components, all Rspress internal references to built-in components will preferentially use your re-exported version.

About @rspress/core/theme-original

@rspress/core/theme-original is used to avoid circular references, only use it when customizing themes.

docs
index.mdx<-- use "@rspress/core/theme"
theme
index.tsx<-- use "@rspress/core/theme-original"
rspress.config.ts
  1. In the docs directory, use @rspress/core/theme, which points to your theme/index.tsx.

  2. In the theme directory, use @rspress/core/theme-original, which always points to Rspress built-in theme components.

Wrap: Pass props/slots

Wrap means adding props to re-exported components. Here's an example of inserting some content before the navbar title:

theme/index.tsx
i18n.json
import { Layout as BasicLayout } from '@rspress/core/theme-original';
import { useI18n } from '@rspress/core';

const Layout = () => {
  const t = useI18n();
  return <BasicLayout beforeNavTitle={<div>{t('some content')}</div>} />;
};

export { Layout };
export * from '@rspress/core/theme-original';
Tip

The Layout component is designed with a series of slot props specifically for wrapping. You can use these props to extend the default theme layout:

Eject: Directly override the entire component

Eject means directly overriding a single Rspress built-in component, using your own version entirely. For this, Rspress provides the rspress eject [component] command to copy the source code of built-in components locally and modify them directly. The steps are as follows:

  1. Execute CLI, Rspress will eject the source code of the specified component to the local theme/components directory, without ejecting dependencies.

  2. Update theme/index.tsx re-export:

theme/index.tsx
// Assuming you ejected the DocFooter component
export { DocFooter } from './components/DocFooter';
export * from '@rspress/core/theme-original';
  1. Modify theme/components/DocFooter.tsx as needed to meet your requirements.

To make it easier for users to eject, Rspress components are split with fine granularity. You can see which components are suitable for eject in Layout Components.

Do you really need eject?

Eject will increase maintenance costs, because when Rspress is updated in the future, these ejected components will not automatically receive updates, and you need to manually compare and merge changes.

Please check if wrap can meet your needs first. Only consider eject when wrap cannot meet your needs.