close
  • English
  • Custom theme

    For your Agent

    If you are using a coding agent, install the rspress-custom-theme Agent Skill to help the agent generate a brand-new theme for you.

    For more information about AI-assisted development with Rspress, see the AI page.

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

    2. For JS / React, Rspress provides a runtime interface based on ESM re-exports, so you can modify or replace built-in components for your own homepage, sidebar, search components, and more.

      On top of this, there are two modes:

      • wrap: Wrap and enhance Rspress built-in components with props or 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 sections introduce these approaches from lighter to deeper customization.

    CSS variables

    Rspress exposes commonly used CSS variables. Compared with rewriting built-in React components, overriding CSS variables is simpler and easier to maintain. View these CSS variables on the UI - CSS Variables page, then override them with:

    docs
    index.mdx
    theme
    index.tsx
    index.css<-- Copy CSS variable code here to override styles
    rspress.config.ts
    theme/index.tsx
    import './index.css';
    export * from '@rspress/core/theme-original';

    Another approach is to use the globalStyles config in rspress.config.ts:

    rspress.config.ts
    import { defineConfig } from '@rspress/core';
    import path from 'path';
    
    export default defineConfig({
      globalStyles: path.join(__dirname, 'styles/index.css'), // Points to your CSS file
    });

    BEM class names

    All built-in Rspress components use the BEM naming convention. You can use these class names to override styles, similar to 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, create a theme directory under the project root, then create an index.ts or index.tsx file inside it to export 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'; 

    When you override built-in components with ESM re-exports, Rspress internal references to those components use your re-exported version first.

    About @rspress/core/theme-original

    @rspress/core/theme-original avoids circular references. Use it only 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

    Wrapping means adding props to re-exported components. Here is an example that inserts 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

    Ejecting means fully replacing a built-in Rspress component with your own version. Rspress provides the rspress eject [component] command to copy built-in component source code locally so you can modify it directly:

    1. Run the CLI. Rspress ejects the specified component source code to the local theme/components directory without ejecting its 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.

    Rspress components are split into fine-grained pieces to make ejecting practical. See which components can be ejected in Layout Components.

    Do you really need eject?

    Ejecting increases maintenance cost. When Rspress is updated, ejected components do not receive updates automatically, so you need to compare and merge changes manually.

    Check whether wrapping meets your needs first. Use eject only when wrapping is not enough.