スキャフォールドされた zudo-doc プロジェクトは意図的に最小限です。1つの設定ファイル、コンテンツ、スタイルシート、そして2つの薄いルートスタブ（[インストール](https://zudo-doc.takazudomodular.com/ja/docs/getting-started/installation#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%A7%8B%E6%88%90)を参照）。それ以外のすべて — レイアウト、クローム、スキーマ、トークン — は `@takazudo/zudo-doc` から出荷され、`node_modules` から消費されます。

その「唯一の設定ファイル」という理想は、よくあるケースをカバーします。このページは、それでは足りないときのための**エスカレーションはしご**です。各段は前の段より侵襲的で、変更が実際に必要とする分だけ登るべきです。段は、実際のプロジェクトがそこに到達しがちな早さで並んでいます。

## はしご

| 段 | 手を伸ばすとき | コスト |
| --- | --- | --- |
| **1. `buildDocsSchema` の上書き** | カスタムの検証付きフロントマターキーが必要 | 関数を1つ置き換え、スキーマを所有する |
| **2. 設定フィールド** | 機能のオン/オフや挙動の調整 | なし — ただのフィールド |
| **3. テーマパック** | 手作業の調整ではなく、完成された見た目一式が欲しい | なし — フィールド1つか CLI コマンド1つ |
| **4. トークンの上書き** | 色・スペーシング・タイポグラフィの再テーマ | `global.css` の `:root` ブロック |
| **5. `zudo-doc eject`** | 再参照するコンテンツ層コンポーネントを変更する必要 | eject したコピーとそのインポートを所有する |
| **6. `chromeBindingsModule`** | 主要クロームの置換や、[カスタム MDX コンポーネント](https://zudo-doc.takazudomodular.com/ja/docs/guides/custom-components#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E7%99%BB%E9%8C%B2-mdxextras)を含むホストコーラブルの注入 | ホストモジュール1つ |
| **7. 自前の `pages/*.tsx`** | ルート全体を自分のものにする必要 | そのルートを所有する |
| **8. デプロイ経路** | 本番公開（特に SSR 機能を伴う場合） | アダプター + `wrangler.toml` + シークレット |
| **9. pre-push / HTML チェックの復元** | ショーケースの検証ゲートを取り戻したい | スクリプトのコピー + 依存追加 |

## 第1段 — カスタムフロントマターキー（`buildDocsSchema`）

これは**唯一の設定という理想が最初に崩れる場所**なので、はしごの先頭に置きます。

他のあらゆる機能は `zudoDoc()` のフィールドです。フロントマターの検証はそうではありません。ドキュメントコレクションは Zod スキーマで検証されますが、「`tier` キーも許可する」と伝える設定フィールドは存在しません。スキーマは**あなたが置き換える関数** — `buildDocsSchema` エスケープハッチです。

デフォルトでは `zudoDoc()` があなたのためにパッケージスキーマを構築します（ガバナンス対応。`tagGovernance` + `tagVocabularyEntries` から導出）。独自のキーを追加するには、デフォルトビルダーをインポートし、その結果を拡張して、新しいビルダーを返します:

```ts title="zfb.config.ts"
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`](https://zudo-doc.takazudomodular.com/ja/docs/reference/host-chrome-bindings)（第6段）と組み合わせると、そのキーから実際にバッジをレンダリングできます。

[Dynamic content unavailable in text export]

`buildDocsSchema` は `ZudoDocConfig` の非シリアライズ可能な**エスケープハッチフィールド**の1つで、`colorSchemes`、`translations`、`directives`、`tagVocabularyEntries` と並びます。これらはインポートグラフを通じて移動する（JSON シリアライズされない）ため、関数や Zod 型を運べます。[設定](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration)を参照してください。



## 第2段 — 設定フィールド

それ以外のほとんどは**フィールドです**。`zudoDoc()` はすべての設定をデフォルト化するので、`zfb.config.ts` には差分だけを並べます:

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    siteName: "My Docs",
    docHistory: true,
    sidebarToggle: true,
    tocToggle: true,
    tocMaxDepth: 3,
    headerNav: [
      { label: "Guides", path: "/docs/guides", categoryMatch: "guides" },
    ],
    footer: { copyright: "© 2026 Me" },
  }),
);
```

**手を伸ばすとき:** 機能をオン/オフにしたり、挙動（TOC の深さ、ナビゲーション、カラーモード、ロケール）を調整するとき。

**限界:** 設定フィールドは*何が存在し、どう振る舞うか*を制御しますが、コンポーネントのピクセルレベルのレンダリングは制御しません。それには第3段〜第5段へ登ります。

デフォルトを含むフィールドの完全な一覧は [設定](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration) リファレンスで、`ZudoDocConfig` 型自身の JSDoc を反映しています。

## 第3段 — テーマパック

トークンを手作業で調整し始める前に、同梱の**テーマパック**が求める見た目をすでに実現していないか確認してください。パックはトークン・フォント・コンポーネントのディテールまで揃った完成済みのデザインバンドルで、設定フィールド1つ、または CLI コマンド1つで適用できます:

```ts title="zfb.config.ts"
zudoDoc({
  siteName: "My Docs",
  themePack: "foundry",
});
```

```sh
pnpm exec zudo-doc theme apply foundry
```

すべてのパックがライト/ダーク両方の値を定義しているため、読者はどのパックでも外観メニューから Light、Dark、System を選べます。System はアクティブなパックに関係なくデバイス設定に従います。`themePackSwitcher: true` を加えると、読者が右下のフライアウトからパックをライブで切り替えられるようになります。

**手を伸ばすとき:** 全体の見た目を変えたくて、同梱パックがそれに合っているとき。

**限界:** インストール済みパックからそのまま選ぶだけです。パックの上で個々のトークンを調整するのは次の段の仕事です。[テーマパック](https://zudo-doc.takazudomodular.com/ja/docs/reference/theme-packs)を参照してください。

## 第4段 — トークンの上書き

スキャフォールドの `src/styles/global.css` は短い `@import` チェーンで、パッケージの `theme.css`（すべての `:root` デザイントークン）、`content.css`、`features.css` を取り込み、その後にあなた用の空の `:root { … }` ブロックが続きます。これはパッケージのインポートの**後**に来るため、そこで再定義したものはカスケードで勝ちます:

```css title="src/styles/global.css"
/* ...package @imports above... */

:root {
  --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` で一度設定します。

**手を伸ばすとき:** 変更が再テーマ — 色、スペーシング、タイポグラフィ、角丸 — であるとき。

**限界:** トークンは再スタイルしますが、マークアップは再構成しません。[デザインシステム](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-system)、[Color](https://zudo-doc.takazudomodular.com/ja/docs/reference/color)、[コンポーネントトークン](https://zudo-doc.takazudomodular.com/ja/docs/reference/component-tokens)を参照してください。

プロジェクトで別のデザインシステムの `:root` も統合する場合は、[別の `@theme` との共存](https://zudo-doc.takazudomodular.com/ja/docs/reference/design-system#%E5%88%A5%E3%81%AE-theme-%E3%81%A8%E3%81%AE%E5%85%B1%E5%AD%98)を参照してください。

## 第5段 — コンポーネントのエジェクト

どのトークンでも変更に届かない — マークアップ自体があなたに合わない — 場合は、プロジェクトが再参照する**コンテンツ層**コンポーネント（たとえば `mdxExtras` 経由）をエジェクトします。エジェクトはそのソースをパッケージからプロジェクトへコピーし、該当するホストインポートをローカルコピーへ書き換えます:

```sh
# eject a component (run via your package manager's bin runner)
pnpm exec zudo-doc eject details
# → copies source into your project and rewrites imports to resolve locally

# see the full list
pnpm exec zudo-doc --help
```

エジェクト可能な18コンポーネントには、3つの異なる範囲があります:

- **コンテンツ層:** `tab-item`、`content-admonition`、`code-group`、`details`。ローカルコピーをレンダリングする必要があるときは、プロジェクト所有の bindings または MDX コンポーネント登録から再参照します。
- **主要クローム:** `header`、`footer`、`breadcrumb`、`toc`、`sidebar`、`doc-pager`。ローカルコピーを対応する `chromeBindings.Header`、`Footer`、`Breadcrumb`、`Toc`、`Sidebar`、`DocPager` スロットへバインドします。
- **入れ子クローム:** `theme-toggle`、`page-loading`、`sidebar-tree-island`、`sidebar-toggle-island`、`desktop-sidebar-toggle-island`、`image-enlarge`、`doc-history`、`site-tree-nav-island`。CLI 警告が示す所有者レベルの binding が必要です。入れ子ファイルをコピーするだけでは、パッケージ所有の親は置き換わりません。

コンテンツ層コンポーネントでは、まずそれをレンダリングするホストコードにローカルインポートを配線してから、ローカルコピーを編集します。`mdxExtras` に必要な bindings とルートスタブの設定は[カスタムコンポーネントガイド](https://zudo-doc.takazudomodular.com/ja/docs/guides/custom-components#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E7%99%BB%E9%8C%B2-mdxextras)にあります。

[Dynamic content unavailable in text export]

エジェクトは、どのコンポーネントを所有しているかを記録するプロベナンスを `.zudo-doc.json` ファイルに書き込みます。このファイルは**最初のエジェクト時に遅延生成**されます — 新しいスキャフォールドには存在しないため、エジェクトしていないプロジェクトは説明不能な設定ファイルを持ちません。エジェクトを戻すには、まず書き換えられた、または手作業で追加したローカルインポートを元の `@takazudo/zudo-doc/...` パッケージインポートへ戻します。その後にコンポーネントディレクトリと `.zudo-doc.json` のエントリを削除します。先にディレクトリを削除すると、それらのインポートが壊れます。



**限界:** エジェクトしたコピーは、そのコンポーネントのパッケージ更新をもう受け取りません — メンテナンスを引き受けることになります。CLI は各 eject を静的に分類します。主要／入れ子クロームはサポート済み binding が見つかるまで大きく警告し、コンテンツ層は静かな手動 `mdxExtras` 案内を出します。eject はソースをコピーし、`chromeBindingsModule` が主要または所有者レベルの置換を実際の描画へ接続するサポート済み継ぎ目です。

**別種のエジェクト — `zudo-doc eject logo`。** このサブコマンドは `eject` という名前を共有しますが、上記のコンポーネントソースコピーとは異なります — `.zudo-doc.json` のプロベナンスにもコンポーネントディレクトリにも一切触れません。これは**アセットの実体化**です — 生成された auto-logo を実ファイルの SVG として描画し、[`logo`](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration#%E3%82%A2%E3%82%A4%E3%83%87%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3%E3%81%A8-url-logo) 設定フィールドをそれを指すように書き換えます。これにより、リクエスト時に生成されるデフォルトの代わりに、編集可能なファイルを所有することになります。

```sh
pnpm exec zudo-doc eject logo
```

これは `public/img/logo.svg` を書き出します — マークは内部の SVG luminance マスクとして表現されているため、自前の `logo` アセットと同じ CSS マスクのヒーロー経路でテーマに追従し続けます — そして `zfb.config.ts` の `logo` を `"/img/logo.svg"` に書き換えます。

- `--seed <name>` — マークの描画に使う `siteName` シードを上書きします。`zfb.config.ts` が正規のスキャフォールド形でない場合（たとえば `zudoDoc({ ...settings })`）は必須です。この場合シードを静的に読み取れないためです。
- `--force` — 既存の `public/img/logo.svg` を上書きします。指定しない場合、コマンドを再実行すると、手作業で編集したかもしれないファイルを黙って上書きするのではなく**きっぱり拒否**します。

[Dynamic content unavailable in text export]

`--seed` はシードを与えるだけで、設定の書き換えまで可能にするわけではありません。正規形でない設定の場合、コマンドは SVG は書き出したうえで `zfb.config.ts` を更新できなかったことを報告し、追加すべき行を表示して**非ゼロで終了**します。仕上げは手作業で行ってください。

```ts title="zfb.config.ts"
export default zudoDoc({
  ...settings,
  logo: "/img/logo.svg",
});
```

CLI はリテラルで手編集可能なフィールド列だけを書き換えます。そのため、スプレッドで制御されたオブジェクトのどこにフィールドを置くべきかを推測せず、拒否します。



## 第6段 — `chromeBindingsModule`（ホストコーラブル）

`packageOwnedRoutes: true`（デフォルト）では、ドキュメントのクロームがパッケージ内部で組み立てられるため、プロジェクト固有のコンテンツをレンダリングするホストファイルがありません。`chromeBindingsModule` はそれを取り戻す継ぎ目です。`chromeBindings` オブジェクトをエクスポートするホストモジュールを指すと、注入ルートがあなたのスロットを拾います — コンテンツヘッダーレンダラー、ホームヒーローの追加要素、カスタムフロントマタープレビューレンダラー、フッタータグローダーなど。

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    siteName: "My Docs",
    chromeBindingsModule: "./src/chrome-bindings.tsx",
  }),
);
```

```tsx title="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,
});
```

新しい scaffold のドキュメントルートスタブは、ロケール版と doc-history 版を含め、すでに `virtual:zudo-doc-chrome-bindings` をインポートして `createChrome` へ渡します。設定フィールドとモジュールを追加するだけで、ルートスタブを fork する必要はありません。自作ルートでは同じオブジェクトを `createChrome(routeCtx, chromeBindings)` の第2引数へ渡してください。完全なパターンは[カスタムコンポーネントガイド](https://zudo-doc.takazudomodular.com/ja/docs/guides/custom-components#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E7%99%BB%E9%8C%B2-mdxextras)にあります。

Design Token Panel には並行チャネル `designTokenPanelConfigModule` があります。パッケージデフォルトのパネルはゼロコンフィグ（`designTokenPanel: true` だけ）で動作し、完全にカスタマイズするには、その設定を `buildDesignTokenPanelConfig(mode)` をエクスポートするホストモジュールに向けます。両チャネルは — ファイルが無いときの大きな声での失敗挙動も含め — [ホストクロームバインディング](https://zudo-doc.takazudomodular.com/ja/docs/reference/host-chrome-bindings)で詳しく説明されています。

## 第7段 — 自前の `pages/*.tsx`

ルート全体を自分のものにする必要があるなら、対応するパスの `.tsx` ファイルを `pages/` に追加します。**同じパスに対して、プロジェクト所有のページは常にパッケージ注入ルートに勝ちます** — ホストファイルが注入をシャドウします。これが完全にカスタムなランディングルートの追加、特定の注入ドキュメントパスの引き取りの方法です。

scaffold のスタブは特別です。`pages/index.tsx` は何もシャドーしません。`/` は注入されないため、これはパッケージホームページを提供する1行の再エクスポートです。`pages/docs/[[...slug]].tsx` は注入されたドキュメントルートをシャドーしますが、任意のカスタマイズ例ではなく、明示的なホスト所有のシームとして残っています。zfb 2.13.1 は注入された動的ルートを dev と build の両方でレンダリングし、スタブはホスト所有権とカスタマイズ性を保ちます。完全な注入とシャドーイングのモデルは[ルーティング規約](https://zudo-doc.takazudomodular.com/ja/docs/develop/routing-conventions#%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%83%AB%E3%83%BC%E3%83%88%E3%81%AE%E6%B3%A8%E5%85%A5%E3%81%A8%E3%82%B7%E3%83%A3%E3%83%89%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%B0)を参照してください。

## 第8段 — デプロイ経路（明示的な拡張ステップ）

最小スキャフォールドは**純粋な静的サイト**をビルドします — `pnpm build` が `dist/` を出力し、任意の静的ホストに置けます。設計上、**アダプターも `wrangler.toml` も出荷しません**。静的エクスポートを超えることは意図的な拡張ステップです:

1. **デプロイアダプターを追加する。** Cloudflare Workers なら、`adapter` シェルフィールドを設定します:

   ```ts title="zfb.config.ts"
   zudoDoc({
     siteName: "My Docs",
     adapter: "@takazudo/zfb-adapter-cloudflare",
   });
   ```

   アダプターは、プリレンダリングをオプトアウトするルート（`prerender = false`）に**必須**です — これがまさに AI アシスタントのエンドポイントの挙動です。

2. **`wrangler.toml` を追加する。** Worker 名、カスタムドメインルート、各種バインディングを宣言します。このファイルは新しいスキャフォールドには存在しません — デプロイを決めたときに作成します。

3. **AI アシスタントを有効化する場合は配線する。** `aiAssistant: true` はpackage-ownedな SSR `/api/ai-chat` seamをマウントします。demo modeでは固定応答を返し、host実装なしでlive modeを選ぶとHTTP 501を返します。package/scaffoldはshowcaseのfull handler、`worker-entry.ts`、`AiChatDailySpendCap`を出荷しません。本物のClaude対応アシスタントには、まずshowcaseと同等のhost-owned `/api/ai-chat` handlerとsource Worker entry/Durable Objectを実装し、その後に次を行います:
   - host handlerを導入した後で`aiChatDemoMode: false`に設定する;
   - `RATE_LIMIT` KV 名前空間を作成し（`wrangler kv namespace create RATE_LIMIT`）、`wrangler.toml` でバインドする;
   - `AI_CHAT_DAILY_SPEND_CAP`を`AiChatDailySpendCap`へバインドし、migration tag
     `v1-ai-chat-daily-spend-cap`と`new_sqlite_classes = ["AiChatDailySpendCap"]`を追加する;
   - `ANTHROPIC_API_KEY` シークレットを追加する（`wrangler secret put ANTHROPIC_API_KEY`）;
   - `aiChatAllowedOrigins` をサイトのオリジンに設定する。

showcaseの[デプロイガイド](https://zudo-doc.takazudomodular.com/ja/docs/guides/deployment)と[AI Assistant APIリファレンス](https://zudo-doc.takazudomodular.com/ja/docs/reference/ai-assistant-api)は、host実装の参照として利用してください（シークレット、ソフトなIPごとのKV、UTC日ごとの正確な許可、CORS、プレビュー制約）。class sourceを用意せず名前だけbindingしても動作しません。

## 第9段 — 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` スクリプトを追加します。

[Dynamic content unavailable in text export]

`gen:z-index` / `check:z-index` のコードジェネレーションも同様に生成プロジェクトから削除されました — 13 のデフォルト z-index ティアは `@takazudo/zudo-doc/theme.css` から無条件に出荷されるため、プロジェクトが*カスタム*ティアセットを保守する場合にのみそのコードジェネレーションを再追加します。単一ティアの上書きは 1 行の `:root` 変更（第4段）であり、コードジェネレーションの問題ではありません。



## 関連ページ

- [設定](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration) — すべての `zudoDoc()` フィールドとそのデフォルト
- [テーマパック](https://zudo-doc.takazudomodular.com/ja/docs/reference/theme-packs) — 同梱パック、スイッチャー UI、theme CLI
- [カスタムコンポーネント](https://zudo-doc.takazudomodular.com/ja/docs/guides/custom-components) — 共有 bindings モジュール経由でプロジェクト所有の MDX コンポーネントを登録する
- [ホストクロームバインディング](https://zudo-doc.takazudomodular.com/ja/docs/reference/host-chrome-bindings) — `chromeBindingsModule` と `designTokenPanelConfigModule` の詳細
- [create-zudo-doc CLI](https://zudo-doc.takazudomodular.com/ja/docs/reference/create-zudo-doc) — スキャフォールドが出力するもの