rspress-custom-theme について
Rspress v2 のテーマをカスタマイズする、ドキュメントサイト開発者向けのガイドスキルです。CSS 変数やクラスの上書きからレイアウトスロット、コンポーネントの置き換えまで扱い、要件を満たす最小限の方法を優先します。
主な機能
- 01CSS 変数による色や余白の調整
- 02BEM クラス上書きによるコンポーネントのスタイル変更
- 03レイアウトスロットによるコンテンツ追加
- 04エクスポートによるコンポーネントやアイコンの置き換え
- 05frontmatter によるページレイアウト制御
活用シーン
- 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 には、軽いものから重いものまで、4 段階のカスタマイズ方法があります。要件を満たす範囲で、常に最も軽い方法を選んでください。軽い方法ほど保守しやすく、Rspress のアップグレード後もそのまま利用できます。
ワークフロー
- ユーザーの目的を理解する — 何を変更したいのでしょうか?(色、レイアウト、コンテンツの挿入、コンポーネント全体の置き換えなど)
- 以下の判断フローに従って適切なレベルを選ぶ
- 必要に応じて
theme/index.tsxをセットアップする(レベル 1A、3、4 で必要です) - このスキルと参照ファイルのパターンに従って実装する
- ユーザーの Rspress のバージョンが v2 であることを確認する(インポート先が
rspress/*ではなく@rspress/core/*であること)
判断フロー
| ユーザーが変更したい内容 | レベル | 方法 |
|---|---|---|
| ブランドカラー、フォント、間隔、シャドウを変更する | 1 | CSS 変数 |
| 特定のコンポーネントのスタイル(境界線、パディングなど)を調整する | 2 | BEM クラスのオーバーライド |
| 既存のコンポーネントの前後にコンテンツ(バナー、フッター、ロゴなど)を追加する | 3 | レイアウトスロット(wrap) |
MDX のレンダリング(カスタム <h1>、<code> など)をオーバーライドする | 3 | components スロット |
| アプリをプロバイダー(状態管理、分析、認証など)でラップする | 4 | Root の取り出し |
| 組み込みアイコン(ロゴ、GitHub、検索など)を置き換える | — | アイコンの再エクスポート |
| 組み込みコンポーネント全体を置き換える | 4 | 対象コンポーネントの取り出し |
| グローバルなフローティングコンポーネント(トップに戻るボタン、チャットウィジェットなど)を追加する | — | globalUIComponents 設定 |
| ページレイアウトの構造(サイドバーを非表示にする、空白のページにするなど)を制御する | — | フロントマターの 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'),
});
変数の全一覧:利用可能な CSS 変数とライト/ダークモードのデフォルト値については、
references/css-variables.mdを参照してください。
レベル 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()。
すべてのスロットと使用例:i18n や MDX コンポーネントのオーバーライドを含む、スロットの完全な一覧と使用パターンについては、
references/layout-slots.mdを参照してください。
レベル 4:eject
組み込みコンポーネントのソースをコピーして、完全に置き換えます。wrap/slots ではカスタマイズできない場合にのみ使用してください。
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 には、UI 全体で使用される 27 個の組み込みアイコンがあります。同じ名前で独自のアイコンコンポーネントを再エクスポートすることで、eject せずに任意のアイコンを置き換えられます。これは同じ 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: '...' },
],
],
});
ページタイプ
フロントマターの pageType で、ページごとのレイアウトを制御します。
| 値 | 説明 |
|---|---|
home | ナビゲーションバー付きのホームページ |
doc | サイドバーとアウトライン付きの標準ドキュメント |
doc-wide | サイドバーとアウトラインなしのドキュメント |
custom | ナビゲーションバーのみのカスタムコンテンツ |
blank | ナビゲーションバーなしのカスタムコンテンツ |
404 | 404 エラーページ |
細かく設定する場合は、navbar: false、sidebar: false、outline: false、footer: false を個別に指定します。
よくある落とし穴
- 循環インポート:
theme/ファイルで@rspress/core/theme-originalではなく@rspress/core/themeを使用すると、無限ループが発生します。 - eject の多用:Layout スロットや CSS 変数で十分な場合に eject すると、アップグレードの負担が増えます。
- 再エクスポート漏れ:
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 コマンド(eject):https://rspress.rs/api/commands