AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Rspress Custom Theme

skill-rstackjs-agent-skills-rspress-custom-theme · by rstackjs

Customize Rspress themes using CSS variables, Layout slots, component wrapping, or component ejection. Use when a user wants to change the look and feel of an Rspress site, override theme components, add custom navigation/sidebar/footer content, inject global providers, or modify the default Rspress theme in any way. Also use when a user mentions theme/index.tsx, Layout slots, BEM class overrides…

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add skill-rstackjs-agent-skills-rspress-custom-theme

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-rstackjs-agent-skills-rspress-custom-theme)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Rspress Custom Theme? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Rspress Custom Theme

Guide for customizing Rspress (v2) themes. Rspress offers four levels of customization, from lightest to heaviest. Always prefer the lightest approach that meets the requirement — lighter approaches are more maintainable and survive Rspress upgrades.

Workflow

  1. Understand the user's goal — what do they want to change? (colors, layout, inject content, replace a component entirely?)
  2. Pick the right level using the decision flow below
  3. Set up theme/index.tsx if needed (Levels 1A, 3, 4 all need it)
  4. Implement following the patterns in this skill and reference files
  5. Verify the user's Rspress version is v2 (imports use @rspress/core/* not rspress/*)

Decision Flow

| User wants to... | Level | Approach | | ---------------------------------------------------------------- | ----- | --------------------------- | | Change brand colors, fonts, spacing, shadows | 1 | CSS variables | | Adjust a specific component's style (borders, padding, etc.) | 2 | BEM class overrides | | Add content around existing components (banners, footers, logos) | 3 | Layout slots (wrap) | | Override MDX rendering (custom `, , etc.) | 3 | components slot | | Wrap the app in a provider (state, analytics, auth) | 4 | Eject Root | | Replace built-in icons (logo, GitHub, search, etc.) | — | Icon re-export | | Completely replace a built-in component | 4 | Eject that component | | Add a global floating component (back-to-top, chat widget) | — | globalUIComponents config | | Control page layout structure (hide sidebar, blank page) | — | Frontmatter pageType` |


theme/index.tsx — The Entry Point

Levels 1A, 3, and 4 all require a theme/index.tsx file in the project root (sibling to docs/). This is the single entry point for all theme customizations:

project/
├── docs/
├── theme/
│   ├── index.tsx        # Theme entry — re-exports + overrides
│   ├── index.css         # CSS variable / BEM overrides (optional)
│   └── components/       # Ejected components (Level 4)
└── rspress.config.ts

Minimal setup:

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

Critical import rule: Inside theme/ files, always import from @rspress/core/theme-original. The path @rspress/core/theme resolves to your own theme/index.tsx, which causes circular imports. (In docs/ MDX files, @rspress/core/theme is fine — it correctly points to your custom theme.)


Level 1: CSS Variables

Override CSS custom properties for brand colors, backgrounds, text, code blocks, and more.

Option Atheme/index.css (use when you also have component overrides in theme/index.tsx):

/* theme/index.css */
:root {
  --rp-c-brand: #7c3aed;
  --rp-c-brand-light: #8b5cf6;
  --rp-c-brand-dark: #6d28d9;
}
.dark {
  --rp-c-brand: #a78bfa;
}

Option BglobalStyles (use when you only need CSS changes, no component overrides):

// rspress.config.ts
export default defineConfig({
  globalStyles: path.join(__dirname, 'styles/custom.css'),
});

> Full variable list: Read references/css-variables.md for all available CSS variables with light/dark defaults.


Level 2: BEM Class Overrides

All built-in components follow BEM naming: .rp-[component]__[element]--[modifier].

Common targets: .rp-nav, .rp-link, .rp-tabs, .rp-codeblock, .rp-codeblock__title, .rp-nav-menu__item--active.

Use these in your CSS file for targeted style changes when CSS variables aren't granular enough.


Level 3: Wrap (Layout Slots)

Inject content at specific positions in the layout without replacing built-in components. Override Layout in theme/index.tsx:

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

export function Layout() {
  return (
    } bottom={} />
  );
}

Use runtime hooks inside slot components — import from @rspress/core/runtime: useDark(), useLang(), useVersion(), usePage(), useSite(), useFrontmatter(), useI18n().

> All slots & examples: Read references/layout-slots.md for the complete slot list and usage patterns including i18n and MDX component overrides.


Level 4: Eject

Copy a built-in component's source for full replacement. Only use when wrap/slots cannot achieve the customization.

rspress eject           # list available components
rspress eject DocFooter # eject to theme/components/DocFooter/

Then re-export in theme/index.tsx (named export takes precedence over the wildcard):

export * from '@rspress/core/theme-original';
export { DocFooter } from './components/DocFooter';

> Component list & patterns: Read references/eject-components.md for available components, workflow, and common patterns.


Custom Icons

Rspress has 27 built-in icons used across the UI. You can replace any of them by re-exporting your own icon component with the same name — no ejection needed. This uses the same theme/index.tsx mechanism: your named export takes precedence over the wildcard re-export.

Icon type: Each icon is a React component or a URL string:

import type { FC, SVGProps } from 'react';
type Icon = FC> | string;

Example 1 — Replace an icon with a custom SVG component:

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

// Named export overrides the wildcard — replaces the GitHub icon site-wide
export const IconGithub = (props: React.SVGProps) => (
  
    
  
);

Example 2 — Use an SVGR import:

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

import CustomGithubIcon from './icons/github.svg?react';
export const IconGithub = CustomGithubIcon;

Using SvgWrapper in MDX or custom components:

import { SvgWrapper, IconGithub } from '@rspress/core/theme';

Available icons: IconArrowDown, IconArrowRight, IconClose, IconCopy, IconDeprecated, IconDown, IconEdit, IconEmpty, IconExperimental, IconExternalLink, IconFile, IconGithub, IconGitlab, IconHeader, IconJump, IconLink, IconLoading, IconMenu, IconMoon, IconScrollToTop, IconSearch, IconSmallMenu, IconSuccess, IconSun, IconTitle, IconWrap, IconWrapped.

> Source: See the icons source for default implementations.


Global UI Components

For components that should render on every page without theme overrides:

// rspress.config.ts
export default defineConfig({
  globalUIComponents: [
    path.join(__dirname, 'components', 'BackToTop.tsx'),
    [
      path.join(__dirname, 'components', 'Analytics.tsx'),
      { trackingId: '...' },
    ],
  ],
});

Page Types

Control layout per page via frontmatter pageType:

| Value | Description | | ---------- | ------------------------------------- | | home | Home page with navbar | | doc | Standard doc with sidebar and outline | | doc-wide | Doc without sidebar/outline | | custom | Custom content with navbar only | | blank | Custom content without navbar | | 404 | 404 error page |

Fine-grained: set navbar: false, sidebar: false, outline: false, footer: false individually.


Common Pitfalls

  • Circular import: Using @rspress/core/theme instead of @rspress/core/theme-original in theme/ files — causes infinite loop.
  • Eject over-use: Ejecting when a Layout slot or CSS variable would suffice — creates upgrade burden.
  • Missing re-export: Forgetting export * from '@rspress/core/theme-original' in theme/index.tsx — breaks all un-overridden components.
  • v1 imports: Using rspress/theme or @rspress/theme-default — these are v1 paths. v2 uses @rspress/core/theme-original.

Reference

  • Custom theme guide:
  • CSS variables:
  • Layout component:
  • Built-in icons:
  • Built-in hooks:
  • CLI commands (eject):

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.