关于 rspress-custom-theme
面向文档站点开发者的 Rspress v2 主题定制指南技能。它涵盖从 CSS 变量、类覆盖到布局插槽和组件替换的方式,并优先选择满足需求的轻量方案。
主要功能
- 01通过 CSS 变量定制颜色与间距
- 02通过 BEM 类覆盖调整组件样式
- 03通过布局插槽添加内容
- 04通过导出替换组件和图标
- 05使用 frontmatter 控制页面布局
适用场景
- 01调整品牌颜色与字体
- 02向文档页面添加横幅或页脚
- 03替换内置图标或组件
- 04设置单个页面的布局
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rstackjs/ agent-skills --skill rspress-custom-theme安装后在 Claude Code 中输入/rspress-custom-theme确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/css-variables.mdeject-components.mdlayout-slots.md详细介绍
Rspress 自定义主题
Rspress(v2)主题自定义指南。Rspress 提供四个级别的自定义方式,从轻量到重量依次排列。始终优先选择满足需求的最轻量方案——轻量方案更易于维护,也能经受 Rspress 升级。
工作流
- 了解用户的目标 — 他们想要更改什么?(颜色、布局、注入内容,还是完全替换某个组件?)
- 使用下方的决策流程选择合适的级别
- 按需设置
theme/index.tsx(级别 1A、3、4 都需要) - 参照本技能和参考文件中的模式进行实现
- 确认用户使用的是 Rspress v2(导入使用
@rspress/core/*,而不是rspress/*)
决策流程
| 用户想要…… | 级别 | 方案 |
|---|---|---|
| 更改品牌颜色、字体、间距、阴影 | 1 | CSS 变量 |
| 调整特定组件的样式(边框、内边距等) | 2 | BEM 类覆盖 |
| 在现有组件周围添加内容(横幅、页脚、徽标) | 3 | 布局插槽(wrap) |
覆盖 MDX 渲染(自定义 <h1>、<code> 等) | 3 | components 插槽 |
| 将应用包装在 provider 中(状态、分析、身份验证) | 4 | 弹出 Root |
| 替换内置图标(徽标、GitHub、搜索等) | — | 图标重新导出 |
| 完全替换内置组件 | 4 | 弹出该组件 |
| 添加全局浮动组件(回到顶部、聊天小组件) | — | globalUIComponents 配置 |
| 控制页面布局结构(隐藏侧边栏、空白页面) | — | Frontmatter pageType |
theme/index.tsx — 入口点
级别 1A、3 和 4 都需要在项目根目录(与 docs/ 同级)中创建 theme/index.tsx 文件。这是所有主题自定义内容的唯一入口点:
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
最简设置:
// theme/index.tsx
import './index.css'; // optional
export * from '@rspress/core/theme-original';
重要的导入规则:在 theme/ 文件中,始终从 @rspress/core/theme-original 导入。路径 @rspress/core/theme 会解析到你自己的 theme/index.tsx,从而导致循环导入。(在 docs/ MDX 文件中,可以使用 @rspress/core/theme——它会正确指向你的自定义主题。)
级别 1:CSS 变量
覆盖 CSS 自定义属性,以设置品牌颜色、背景、文本、代码块等样式。
选项 A — theme/index.css(同时在 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;
}
选项 B — globalStyles(只需更改 CSS、不需要组件覆盖时使用):
// rspress.config.ts
export default defineConfig({
globalStyles: path.join(__dirname, 'styles/custom.css'),
});
完整变量列表:阅读
references/css-variables.md,查看所有可用的 CSS 变量及其浅色/深色模式默认值。
级别 2:BEM 类覆盖
所有内置组件都遵循 BEM 命名规范:.rp-[component]__[element]--[modifier]。
常用目标:.rp-nav、.rp-link、.rp-tabs、.rp-codeblock、.rp-codeblock__title、.rp-nav-menu__item--active。
当 CSS 变量不够精细时,可在 CSS 文件中使用这些类来针对性地更改样式。
级别 3:wrap(布局插槽)
在布局中的特定位置注入内容,而不替换内置组件。在 theme/index.tsx 中覆盖 Layout:
// theme/index.tsx
import { Layout as OriginalLayout } from '@rspress/core/theme-original';
export * from '@rspress/core/theme-original';
export function Layout() {
return (
<OriginalLayout beforeNavTitle={<MyLogo />} bottom={<CustomFooter />} />
);
}
在插槽组件中使用运行时钩子——从 @rspress/core/runtime 导入:useDark()、useLang()、useVersion()、usePage()、useSite()、useFrontmatter()、useI18n()。
所有插槽及示例:阅读
references/layout-slots.md,了解完整的插槽列表和使用模式,包括 i18n 和 MDX 组件覆盖。
第 4 级:弹出
复制内置组件的源代码,以便完全替换。仅当包装或插槽无法实现所需的自定义时才使用。
rspress eject # list available components
rspress eject DocFooter # eject to theme/components/DocFooter/
然后在 theme/index.tsx 中重新导出(命名导出优先于通配符导出):
export * from '@rspress/core/theme-original';
export { DocFooter } from './components/DocFooter';
组件列表与模式:阅读
references/eject-components.md,了解可用组件、工作流和常见模式。
自定义图标
Rspress 内置了 27 个图标,供 UI 各处使用。你可以重新导出一个同名的自定义图标组件来替换其中任意图标,无需弹出。这使用相同的 theme/index.tsx 机制:你的命名导出优先于通配符重新导出。
图标类型:每个图标都是 React 组件或 URL 字符串:
import type { FC, SVGProps } from 'react';
type Icon = FC<SVGProps<SVGSVGElement>> | string;
示例 1 — 将图标替换为自定义 SVG 组件:
// 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<SVGSVGElement>) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" {...props}>
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 ..." fill="currentColor" />
</svg>
);
示例 2 — 使用 SVGR 导入:
// theme/index.tsx
export * from '@rspress/core/theme-original';
import CustomGithubIcon from './icons/github.svg?react';
export const IconGithub = CustomGithubIcon;
在 MDX 或自定义组件中使用 SvgWrapper:
import { SvgWrapper, IconGithub } from '@rspress/core/theme';
<SvgWrapper icon={IconGithub} width={24} height={24} />
可用图标: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。
源代码:查看图标源代码,了解默认实现。
全局 UI 组件
对于应在每个页面上渲染、且无需主题覆盖的组件:
// rspress.config.ts
export default defineConfig({
globalUIComponents: [
path.join(__dirname, 'components', 'BackToTop.tsx'),
[
path.join(__dirname, 'components', 'Analytics.tsx'),
{ trackingId: '...' },
],
],
});
页面类型
通过 frontmatter pageType 控制每个页面的布局:
| 值 | 描述 |
|---|---|
home | 带导航栏的主页 |
doc | 带侧边栏和大纲的标准文档 |
doc-wide | 不带侧边栏和大纲的文档 |
custom | 仅带导航栏的自定义内容 |
blank | 不带导航栏的自定义内容 |
404 | 404 错误页面 |
更精细的设置:分别设置 navbar: false、sidebar: false、outline: false、footer: false。
常见问题
- 循环导入:在
theme/文件中使用@rspress/core/theme而不是@rspress/core/theme-original— 会导致无限循环。 - 过度弹出:在 Layout 插槽或 CSS 变量足以满足需求时仍选择弹出 — 会增加升级负担。
- 缺少重新导出:忘记在
theme/index.tsx中添加export * from '@rspress/core/theme-original'— 会导致所有未覆盖的组件无法使用。 - v1 导入:使用
rspress/theme或@rspress/theme-default— 这些是 v1 路径。v2 使用@rspress/core/theme-original。
参考资料
- 自定义主题指南:https://rspress.rs/guide/basic/custom-theme
- CSS 变量:https://rspress.rs/ui/vars
- Layout 组件:https://rspress.rs/ui/layout-components/layout
- 内置图标:https://rspress.rs/ui/icons/
- 内置钩子:https://rspress.rs/ui/hooks/
- CLI 命令(弹出):https://rspress.rs/api/commands