zudo-doc のカスタマイズ
最小→拡張のエスカレーションはしご — 1行の設定フィールドから完全なソース制御まで、手を伸ばす順番で。
スキャフォールドされた zudo-doc プロジェクトは意図的に最小限です。1つの設定ファイル、コンテンツ、スタイルシート、そして2つの薄いルートスタブ(インストールを参照)。それ以外のすべて — レイアウト、クローム、スキーマ、トークン — は @takazudo/zudo-doc から出荷され、node_modules から消費されます。
その「唯一の設定ファイル」という理想は、よくあるケースをカバーします。このページは、それでは足りないときのためのエスカレーションはしごです。各段は前の段より侵襲的で、変更が実際に必要とする分だけ登るべきです。段は、実際のプロジェクトがそこに到達しがちな早さで並んでいます。
はしご
| 段 | 手を伸ばすとき | コスト |
|---|---|---|
1. buildDocsSchema の上書き | カスタムの検証付きフロントマターキーが必要 | 関数を1つ置き換え、スキーマを所有する |
| 2. 設定フィールド | 機能のオン/オフや挙動の調整 | なし — ただのフィールド |
| 3. トークンの上書き | 色・スペーシング・タイポグラフィの再テーマ | global.css の @theme ブロック |
4. zudo-doc eject | コンポーネントのマークアップ自体を変える必要 | eject したコピーを所有する |
5. chromeBindingsModule | 注入ルートにホストのコンテンツ/コーラブルを差し込む | ホストモジュール1つ |
6. 自前の pages/*.tsx | ルート全体を自分のものにする必要 | そのルートを所有する |
| 7. デプロイ経路 | 本番公開(特に SSR 機能を伴う場合) | アダプター + wrangler.toml + シークレット |
| 8. pre-push / HTML チェックの復元 | ショーケースの検証ゲートを取り戻したい | スクリプトのコピー + 依存追加 |
第1段 — カスタムフロントマターキー(buildDocsSchema)
これは唯一の設定という理想が最初に崩れる場所なので、はしごの先頭に置きます。
他のあらゆる機能は zudoDoc() のフィールドです。フロントマターの検証はそうではありません。ドキュメントコレクションは Zod スキーマで検証されますが、「tier キーも許可する」と伝える設定フィールドは存在しません。スキーマはあなたが置き換える関数 — buildDocsSchema エスケープハッチです。
デフォルトでは zudoDoc() があなたのためにパッケージスキーマを構築します(ガバナンス対応。tagGovernance + tagVocabularyEntries から導出)。独自のキーを追加するには、デフォルトビルダーをインポートし、その結果を拡張して、新しいビルダーを返します:
import { defineConfig } from "zfb/config";
import { zudoDoc } from "@takazudo/zudo-doc/config";
import { buildDocsSchema } from "@takazudo/zudo-doc/docs-schema";
import { z } from "zod";
export default defineConfig(
zudoDoc({
siteName: "My Docs",
// Replace the schema builder entirely. Start from the package default,
// then extend it with your own validated frontmatter keys.
buildDocsSchema: () =>
buildDocsSchema({ tagGovernance: "off" }).extend({
tier: z.enum(["core", "opt-in"]).optional(),
reviewed_by: z.string().optional(),
}),
}),
);これでページは tier: core をフロントマターで宣言でき、ビルド時に検証されます。これを docContentHeaderExtras(第5段)と組み合わせると、そのキーから実際にバッジをレンダリングできます。
Note
buildDocsSchema は ZudoDocConfig の非シリアライズ可能なエスケープハッチフィールドの1つで、colorSchemes、translations、directives、tagVocabularyEntries と並びます。これらはインポートグラフを通じて移動する(JSON シリアライズされない)ため、関数や Zod 型を運べます。設定を参照してください。
第2段 — 設定フィールド
それ以外のほとんどはフィールドです。zudoDoc() はすべての設定をデフォルト化するので、zfb.config.ts には差分だけを並べます:
export default defineConfig(
zudoDoc({
siteName: "My Docs",
docHistory: true,
sidebarToggle: true,
tocMaxDepth: 3,
headerNav: [
{ label: "Guides", path: "/docs/guides", categoryMatch: "guides" },
],
footer: { copyright: "© 2026 Me" },
}),
);手を伸ばすとき: 機能をオン/オフにしたり、挙動(TOC の深さ、ナビゲーション、カラーモード、ロケール)を調整するとき。
限界: 設定フィールドは何が存在し、どう振る舞うかを制御しますが、コンポーネントのピクセルレベルのレンダリングは制御しません。それには第3段や第4段へ登ります。
デフォルトを含むフィールドの完全な一覧は 設定 リファレンスで、ZudoDocConfig 型自身の JSDoc を反映しています。
第3段 — トークンの上書き
スキャフォールドの src/ は短い @import チェーンで、パッケージの theme.css(すべての @theme デザイントークン)、content.css、features.css を取り込み、その後にあなた用の空の @theme { … } ブロックが続きます。これはパッケージのインポートの後に来るため、そこで再定義したものはカスケードで勝ちます:
/* ...package @imports above... */
@theme {
--color-accent: oklch(0.6 0.2 250);
--font-sans: "Inter", system-ui, sans-serif;
--z-index-modal: 200; /* override a single default z-index tier */
}グローバルトークンを読むすべての要素に触れずにコンポーネント単位で再ブランディングするために、パッケージは --zdc-* コンポーネントトークン(見出しフォント、本文フォント、カード角丸、TOC 幅など)も公開しています。:root で一度設定します。
手を伸ばすとき: 変更が再テーマ — 色、スペーシング、タイポグラフィ、角丸 — であるとき。
限界: トークンは再スタイルしますが、マークアップは再構成しません。デザインシステム、Color、コンポーネントトークンを参照してください。
第4段 — コンポーネントのエジェクト
どのトークンでも変更に届かない — マークアップ自体があなたに合わない — 場合は、コンポーネントをエジェクトします。エジェクトはそのソースをパッケージからプロジェクトへコピーし、ファイルを直接所有できるようにします:
# eject a component (run via your package manager's bin runner)
pnpm exec zudo-doc eject header
# → copies source into your project and rewrites imports to resolve locally
# see the full list
pnpm exec zudo-doc --helpエジェクト可能な18コンポーネント:
header, footer, breadcrumb, toc, sidebar, theme-toggle, page-loading, tab-item, doc-pager, content-admonition, code-group, details, sidebar-tree-island, sidebar-toggle-island, desktop-sidebar-toggle-island, image-enlarge, doc-history, site-tree-nav-island
エジェクト後は、ローカルコピーを編集します。変更は pnpm dev で即座に反映されます。
Note
エジェクトは、どのコンポーネントを所有しているかを記録するプロベナンスを .zudo-doc.json ファイルに書き込みます。このファイルは最初のエジェクト時に遅延生成されます — 新しいスキャフォールドには存在しないため、エジェクトしていないプロジェクトは説明不能な設定ファイルを持ちません。コンポーネントのディレクトリと .zudo-doc.json のエントリを削除すれば、パッケージ版に戻ります。
限界: エジェクトしたコピーは、そのコンポーネントのパッケージ更新をもう受け取りません — メンテナンスを引き受けることになります。
第5段 — chromeBindingsModule(ホストコーラブル)
packageOwnedRoutes: true(デフォルト)では、ドキュメントのクロームがパッケージ内部で組み立てられるため、プロジェクト固有のコンテンツをレンダリングするホストファイルがありません。chromeBindingsModule はそれを取り戻す継ぎ目です。chromeBindings オブジェクトをエクスポートするホストモジュールを指すと、注入ルートがあなたのスロットを拾います — コンテンツヘッダーレンダラー、ホームヒーローの追加要素、カスタムフロントマタープレビューレンダラー、フッタータグローダーなど。
export default defineConfig(
zudoDoc({
siteName: "My Docs",
chromeBindingsModule: "./src/chrome-bindings.tsx",
}),
);import { defineChromeBindings } from "@takazudo/zudo-doc/chrome-bindings";
export const chromeBindings = defineChromeBindings({
docContentHeaderExtras: ({ entry }) =>
entry.data.tier === "core" ? <span class="...">Core</span> : null,
});Design Token Panel には並行チャネル designTokenPanelConfigModule があります。パッケージデフォルトのパネルはゼロコンフィグ(designTokenPanel: true だけ)で動作し、完全にカスタマイズするには、その設定を buildDesignTokenPanelConfig(mode) をエクスポートするホストモジュールに向けます。両チャネルは — ファイルが無いときの大きな声での失敗挙動も含め — ホストクロームバインディングで詳しく説明されています。
第6段 — 自前の pages/*.tsx
ルート全体を自分のものにする必要があるなら、対応するパスの .tsx ファイルを pages/ に追加します。同じパスに対して、プロジェクト所有のページは常にパッケージ注入ルートに勝ちます — ホストファイルが注入をシャドウします。これがホームページの置き換え、完全にカスタムなランディングルートの追加、特定のドキュメントパスの引き取りの方法です。
2つのスキャフォールドスタブ(pages/、pages/docs/[[...slug]].tsx)自体が、この優先順位を使う普通のホストページです。拡張したり兄弟を追加したりできます。ルートがどのように列挙されシャドウされるかはルーティング規約を参照してください。
第7段 — デプロイ経路(明示的な拡張ステップ)
最小スキャフォールドは純粋な静的サイトをビルドします — pnpm build が dist/ を出力し、任意の静的ホストに置けます。設計上、アダプターも wrangler.toml も出荷しません。静的エクスポートを超えることは意図的な拡張ステップです:
デプロイアダプターを追加する。 Cloudflare Workers なら、
adapterシェルフィールドを設定します:zfb.config.tszudoDoc({ siteName: "My Docs", adapter: "@takazudo/zfb-adapter-cloudflare", });アダプターは、プリレンダリングをオプトアウトするルート(
prerender = false)に必須です — これがまさに AI アシスタントのエンドポイントの挙動です。wrangler.tomlを追加する。 Worker 名、カスタムドメインルート、各種バインディングを宣言します。このファイルは新しいスキャフォールドには存在しません — デプロイを決めたときに作成します。AI アシスタントを有効化する場合は配線する。
aiAssistant: trueは SSR の/ルートをマウントします。デフォルトではデモモードで出荷されます(api/ ai- chat aiChatDemoModeは設定上デフォルトfalseですが、ライブバックエンドに切り替えるまでスキャフォールドのチャットは静的デモです)。本物の Claude 対応アシスタントには次が必要です:aiChatDemoMode: falseに設定する;RATE_LIMITKV 名前空間を作成し(wrangler kv namespace create RATE_LIMIT)、wrangler.tomlでバインドする;ANTHROPIC_API_KEYシークレットを追加する(wrangler secret put ANTHROPIC_API_KEY);aiChatAllowedOriginsをサイトのオリジンに設定する。
完全なランブック(シークレット、KV、CORS、レート制限)はデプロイガイドと AI Assistant API リファレンスを参照してください。
第8段 — pre-push と HTML バリデーションの復元
最小スキャフォールドは、ショーケースが実行する検証ゲートを削除しています — 小さなドキュメントセットには重荷だったためです。プロジェクトが成長して取り戻したくなったら、明示的に追加します:
pre-push 検証(
b4push)。 スキャフォールドはscripts/もrun- b4push. sh b4pushの package スクリプトも出荷しなくなりました。before-push スイートを復元するには、自前のスクリプト(format → typecheck → build → link check)を追加し、package.jsonスクリプトとして配線します。ショーケースのscripts/が参照実装です。run- b4push. sh HTML バリデーション。 生成される
package.jsonにはcheck:html/html-validateステップ(および.htmlvalidate.json)が含まれなくなりました。ビルド済み HTML を検証するには、html-validateを dev 依存として追加し、.htmlvalidate.jsonを復元し、dist/に対して実行するcheck:htmlスクリプトを追加します。
Note
gen:z-index / check:z-index のコードジェネレーションも同様に生成プロジェクトから削除されました — 13 のデフォルト z-index ティアは @takazudo/ から無条件に出荷されるため、プロジェクトがカスタムティアセットを保守する場合にのみそのコードジェネレーションを再追加します。単一ティアの上書きは 1 行の @theme 変更(第3段)であり、コードジェネレーションの問題ではありません。
関連ページ
設定 — すべての
zudoDoc()フィールドとそのデフォルトホストクロームバインディング —
chromeBindingsModuleとdesignTokenPanelConfigModuleの詳細create-zudo-doc CLI — スキャフォールドが出力するもの
v3 からの移行 — 既存の生成プロジェクトをこの形状へ移す