## 概要

zudo-docは各ドキュメントページのgitリビジョン履歴を表示できます。`docHistory`を有効にし、`DocHistory`クロームバインディングを設定すると、各詳細ページに**History**ボタンが表示され、過去のリビジョンを閲覧したり、行単位のdiffビューアで任意の2つのバージョンを比較できるサイドパネルが開きます。

これは以下の用途に便利です：

- ドキュメントが時間の経過とともにどのように変化したかを確認する
- リビジョン間で何が変更されたかを理解する
- ドキュメント全体のコンテンツ変更を監査する

[Dynamic content unavailable in text export]

この機能はドキュメントがgitリポジトリで管理されている必要があります。履歴は各ファイルに関連するgitコミットから抽出されます。



## ドキュメント履歴の有効化

`zfb.config.ts`で`docHistory`を`true`に設定します：

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    // ...
    docHistory: true,
  }),
);
```

新しい scaffold は `docHistory` を選択したとき、実際の History アイランドを生成されるすべてのルート形状へ静的に配線します。ボタン用の bindings モジュールやルート編集は不要です。古い既存 scaffold では、各ドキュメントスタブを現在の生成形状へ更新します。`DocHistory` を静的にインポートし、`chromeBindings` の後から重ねることで、ほかのホストスロットを落とさずアイランドをスキャナーから到達可能に保ちます。

この機能はビルドを高速に保つため、**デフォルトでは無効**です。

[Dynamic content unavailable in text export]

Compare ビューの行単位 diff 表示にはオプショナルピア依存の `diff` が必要です。`create-zudo-doc` は `docHistory` が選択されたとき — 直接選択された場合と、`docHistory` を強制的に有効化する `bodyFootUtilArea` 経由の場合の両方で — `package.json` に `diff` を自動的に追加します。ジェネレーターを介さず既存プロジェクトで手動により `docHistory` を有効化した場合は、自分で `pnpm add diff` を実行してください。オプショナルピアの契約全体（`math` の `katex` 要件と対応します）については、[設定 — docHistory](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration#%E3%82%B5%E3%82%A4%E3%83%88%E8%A8%AD%E5%AE%9A-dochistory) を参照してください。



## 日付だけを表示する

履歴ビューアを使わずにgit由来のメタデータを表示するには、`zfb.config.ts`を手動で編集します。`docHistoryUi`と`docMetainfoFields`に新しいCLIフラグはありません。

```ts title="zfb.config.ts"
export default defineConfig(
  zudoDoc({
    docHistory: true,
    docHistoryUi: false,
    docMetainfo: true,
    docMetainfoFields: ["updated"],
  }),
);
```

preBuildのCreated/Updated/Authorマニフェストは維持されます。メタデータの表示には、従来どおり`chromeBindingsModule`経由で`docHistoryMeta`にマニフェストを渡す必要があります（[設定リファレンス](https://zudo-doc.takazudomodular.com/ja/docs/guides/configuration#%E3%82%B5%E3%82%A4%E3%83%88%E8%A8%AD%E5%AE%9A-docmetainfo)）。`["updated"]`は日付書式で整形した表示値がCreatedと同じでもUpdatedを表示し、`[]`はメタデータブロックを描画しません。

`docHistoryUi: false`では履歴ボタンとDocHistoryアイランドを描画せず、プラグインの履歴JSON生成と開発時のプロキシも停止します。ソース表示リンクは維持されます。ページの`doc_history: true`や`bodyFootUtilArea.docHistory: true`でこの全体設定を上書きすることはできません。

ホスト側に独立したCIの`build-history`ジョブがある場合は、そのジョブと成果物のアップロード・ダウンロード・マージ処理を削除してください。単独の生成CLIはサイト設定を読まないため、呼び出せば引き続き生成します。不要になった`dev:history`プロセスもホストの開発スクリプトから外せます。設定変更だけでこれらのスクリプトや既存の出力ファイルが削除されることはありません。

### 環境変数との関係

以下は`docHistory: true`の場合です。上の行が優先されます。「通常」は、利用可能なgit履歴からpreBuildマニフェストを生成することを示します。

| 条件 | preBuildメタデータ | `docHistoryUi: true`のJSON | `docHistoryUi: false`のJSON |
|---|---|---|---|
| `SKIP_DOC_HISTORY=1` | 空のマニフェスト | 生成しない | 生成しない |
| `DOC_HISTORY_SKIP_POSTBUILD=1` | 通常 | 生成しない | 生成しない（指定は不要） |
| `GEN_DOC_HISTORY=1` | 通常 | 生成する | 生成しない（UI設定が優先） |
| `CI` / `GITHUB_ACTIONS`が有効 | 通常 | 生成する | 生成しない（UI設定が優先） |
| 上記以外のローカルビルド | 通常 | 生成しない | 生成しない |

日付を残したい場合は`SKIP_DOC_HISTORY=1`を設定しないでください。`docHistoryUi: false`なら`DOC_HISTORY_SKIP_POSTBUILD=1`は不要です。以下の履歴ビューア・JSON・プロキシの説明は、`docHistoryUi`を有効にした場合に適用されます。

## ページごとの表示制御

`docHistory`がグローバルに有効化されたあと、各ページは以下の2つのルールで**History**ボタンを表示するかどうかを決定します。

1. **カテゴリインデックスページの自動抑制** — エントリIDが`/index`で終わるページ（例：`guides/index.mdx`）は、デフォルトでボタンを非表示にします。これらのページは通常ナビゲーションのハブやランディングページであり、リビジョン履歴を表示する意味が薄いためです。
2. **詳細ページはデフォルトで表示** — カテゴリインデックスでない具体的なリーフページはすべてボタンを表示します。

`doc_history`フロントマターフラグでページごとにデフォルトを上書きできます。

```yaml
---
title: My Page
doc_history: false # always hide the button on this page
---
```

```yaml
---
title: My Category Index
doc_history: true # opt back in even though this is an index page
---
```

全体の`docHistory`と`docHistoryUi`が有効な場合、フロントマターの指定はページ種別による既定の表示をどちらの方向にも上書きします。

| ページの種類 | フロントマターなし | `doc_history: true` | `doc_history: false` |
| --- | --- | --- | --- |
| 詳細ページ（リーフ） | 表示 | 表示 | 非表示 |
| カテゴリインデックスページ（`*/index`） | 非表示 | 表示 | 非表示 |

インデックスページにそれなりの分量の本文があり、変更履歴を残す価値がある場合は`doc_history: true`を指定してください。逆に、自動生成された詳細ページや、コミット履歴を表に出したくない詳細ページには`doc_history: false`を指定します。

## 履歴ビューアの使用方法

有効にすると、各詳細ページの本文とフッターの間にある [Body Foot Util エリア](https://zudo-doc.takazudomodular.com/ja/docs/guides/body-foot-util-area) の中に **History** ボタンが表示されます。カテゴリインデックスページではデフォルトで非表示です。詳しくは上記[ページごとの表示制御](https://zudo-doc.takazudomodular.com/ja/docs/guides/doc-history#%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%94%E3%81%A8%E3%81%AE%E8%A1%A8%E7%A4%BA%E5%88%B6%E5%BE%A1)を参照してください。

### リビジョンの閲覧

ボタンをクリックするとリビジョンパネルが開きます。右側からスライドインし、現在のドキュメントを変更したすべてのgitコミットが新しい順に表示されます。各エントリには以下が表示されます：

- **コミットハッシュ**（短縮形）
- コミットの**日付**
- **著者**名
- **コミットメッセージ**（1行目）

### リビジョンの比較

2つのリビジョン間のdiffを表示するには：

1. コミットの横にある**A**ボタンをクリックして**A**（古いリビジョン）を選択
2. 別のコミットの横にある**B**ボタンをクリックして**B**（新しいリビジョン）を選択
3. **Compare**ボタンをクリック

diffビューアは**サイドバイサイド比較**を表示します — 左側に古いリビジョン、右側に新しいリビジョン：

- **緑色の背景** — 新しいリビジョンで追加された行（右側）
- **赤色の背景** — 古いリビジョンから削除された行（左側）
- **灰色のセル** — 一方に対応する行がない空のプレースホルダー
- **変更なしの行** — 両側に表示されるコンテキスト

[Dynamic content unavailable in text export]

デフォルトでは、Aは2番目に新しいコミットに、Bは最新のコミットに設定されるため、**Compare**をクリックするだけで最新の変更をすぐに比較できます。



### キーボードショートカット

- **Escape** — 履歴パネルを閉じる
- 別のページに移動するとパネルは自動的に閉じます

## 仕組み

git履歴の抽出はスタンドアロンパッケージ`@takazudo/zudo-doc-history-server`（`packages/doc-history-server/`に配置）が処理します。このパッケージは開発用と本番ビルド用の2つのモードで動作します。

### ビルドモード

本番環境では、スタンドアロンCLIジェネレーターがすべてのコンテンツファイルをバッチ処理し、JSONの履歴ファイルを`dist/doc-history/`に書き出します。これはzfbサイトビルドと並行した独立したCIジョブとして実行されます：

- **build-site**ジョブ：フルクローン（`fetch-depth: 0`）、`pnpm build`でzfbサイトをビルド（`SKIP_DOC_HISTORY`なし — preBuildがSSGメタブロック生成のためにフルgit履歴が必要）
- **build-history**ジョブ：フルクローン（`fetch-depth: 0`）、`@takazudo/zudo-doc-history-server generate`を実行
- **deploy**ジョブ：両方のアーティファクトをマージしてデプロイ

この並列戦略により、履歴生成（フルgitクローンを必要とし、すべてのコミットを走査する）がzfbビルドとは独立して実行されるため、合計CIビルド時間が短縮されます。

[Dynamic content unavailable in text export]

`dist/doc-history/`内のページごとのドロップダウンJSONはCIでは自動的に生成されますが、**ローカル**ビルドではオプトインです。単に`pnpm build`を実行してから`pnpm preview`しても、履歴ドロップダウンは**表示されません** — Created/Updated/Authorブロックは引き続き表示され、ドロップダウンのデータのみが欠落します。含めるには、次のコマンドでビルドしてください：

```sh
GEN_DOC_HISTORY=1 pnpm build
```

これは、ローカルでビルドした`dist/`をプレビューする場合や、オフラインリーダーをバンドルする場合に役立ちます。詳細は[デプロイガイド](https://zudo-doc.takazudomodular.com/ja/docs/guides/deployment)を参照してください。

逆に、作成日・更新日・著者のメタデータは維持しつつ、このpostBuildステップだけを明示的にスキップしたいシャロークローンのCIバリアントでは、`SKIP_DOC_HISTORY=1`の代わりに`DOC_HISTORY_SKIP_POSTBUILD=1`を設定できます — デプロイガイドの決定表を参照してください。



出力構造はコンテンツディレクトリをミラーします：

```
dist/doc-history/
  getting-started.json
  guides/writing-docs.json
  guides/color.json
  ja/getting-started.json      # locale-prefixed
  ja/guides/writing-docs.json
```

### 開発モード

開発モードでは、doc-history-serverがポート4322でスタンドアロンREST APIサーバーとして実行され、zfb開発サーバーと同時に起動されます。これは既存プロジェクトで`docHistory: true`を設定するだけで自動的に得られるものではありません — `docHistory`を選択した新規`create-zudo-doc` scaffoldは、`dev`スクリプトとして`run-parallel dev:zfb dev:history`（`zfb dev`とインストール済みの`doc-history-server`バイナリを同時に実行）を生成します。これは、単純な`zfb dev`だけではポート4322のサーバーが起動しないためです。doc-historyのzfbプラグインの`devMiddleware`フックがブラウザからの`/doc-history/*`リクエストをこのサーバーにプロキシします。

`run-parallel`は末尾の引数を転送しないため、これらのscaffoldで`pnpm dev -- --host 0.0.0.0`を渡すと、静かに無視されるのではなく対処方法を示すエラーになります（置き換え前の`run-p`は静かに無視していました）。LANアクセスが必要な場合は代わりに専用の`pnpm dev:network`スクリプトを使ってください。zfbだけが`0.0.0.0`にバインドされ、doc-history-serverはループバック限定のまま（同じ`/doc-history/*`プロキシ経由でアクセスされます）。それ以外のzfbフラグを渡したい場合は、`pnpm dev`経由ではなく`<pm> run dev:zfb -- <flags>`でzfbプロセスへ直接転送してください。

履歴パネルを開くと、その場でgitコマンドが実行されます -- 事前生成は不要です。サーバーのファイルインデックスは10秒ごとにリフレッシュされるため、新しいファイルやリネームされたファイルが自動的に検出されます。これにより、履歴は最新のコミットと常に同期されます。

[Dynamic content unavailable in text export]

`docHistory`を有効にするとビルド時間が増加します。すべてのコンテンツファイルのgit履歴を抽出する必要があるためです。多数のファイルと深い履歴を持つ大規模なドキュメントサイトでは、ビルドに顕著な時間が追加される場合があります。デフォルトの上限はドキュメントあたり**50リビジョン**です。



### 本番出力サイズ

zudo-docはサーバーサイドランタイムなしの完全な静的サイトを生成するため、リクエスト時に`git`コマンドを実行するサーバーがありません。代わりに、ビルドステップですべての履歴データを事前抽出し、`dist/doc-history/`ディレクトリに静的JSONファイルとして出力します。

各JSONファイルには**すべてのリビジョンでの完全なファイル内容**（最大50コミット）が含まれます。これにより、合計出力サイズは以下に比例します：

- ドキュメントファイルの数
- ファイルあたりのgitコミット数
- 各リビジョンでの各ファイルのサイズ

小〜中規模のドキュメントサイトでは通常無視できる程度です。深い履歴を持つ大規模サイトでは、`doc-history/`ディレクトリが大幅に増加する可能性があります。これらのファイルはオンデマンドでのみ取得されるため（ユーザーがHistoryボタンをクリックした時）、初期ページ読み込みには影響しません — ただし、デプロイサイズには追加されます。

[Dynamic content unavailable in text export]

本番でメタデータだけが必要なら、`docHistory: true`と`docHistoryUi: false`を組み合わせ、ホストの独立した履歴生成ジョブを削除してください。リビジョンJSONを配信せずに日付を維持できます。どちらも不要なら`docHistory: false`にします。



## ローカライゼーションサポート

ドキュメント履歴は設定されたすべてのロケールで動作します。各ロケールのコンテンツディレクトリは、ロケールコードがプレフィックスされた独自の履歴ファイルセットを生成します：

- 英語ドキュメント：`/doc-history/{slug}.json`
- 日本語ドキュメント：`/doc-history/ja/{slug}.json`
- ドイツ語ドキュメント：`/doc-history/de/{slug}.json`

履歴パネルは現在のページに基づいて適切なロケール固有の履歴を自動的にリクエストします。

## 技術詳細

### データ形式

各ドキュメントの履歴は以下の構造のJSONファイルとして保存されます：

```ts
interface DocHistoryData {
  slug: string;          // Document route path
  filePath: string;      // File path in the repository
  entries: Array<{
    hash: string;        // Full commit hash
    date: string;        // ISO 8601 date
    author: string;      // Commit author name
    message: string;     // Commit message (first line)
    content: string;     // Full file content at this revision
  }>;
}
```

### Diffアルゴリズム

diffビューアは[`diff`](https://www.npmjs.com/package/diff)ライブラリの`diffLines`関数を使用して、2つのリビジョン間の行レベルの差分を計算します。GitHubのスプリットdiffビューに似たサイドバイサイドのテーブルレイアウトで表示されます。隣接する削除ブロックと追加ブロックは同じ行にペアリングされるため、何が変更されたかを一目で確認できます。

### リネーム追跡

履歴抽出は`git log --follow`を使用してファイルのリネームを追跡します。ドキュメントが移動またはリネームされた場合、リネーム前のコミットを含む完全な履歴が保持されます。

[Dynamic content unavailable in text export]

Historyコンポーネントは遅延ハイドレートされるクライアントアイランドです — ページがアイドル状態になってから動作するため、初期ページ読み込みパフォーマンスに影響しません。



## doc-history-serverパッケージ

履歴抽出ロジックはzfbビルドパイプライン内ではなく、スタンドアロンパッケージ（`packages/doc-history-server/`）に配置されています。この設計により以下が可能になります：

- **並列CIビルド** -- 履歴生成とサイトビルドが独立したジョブとして実行可能
- **独立した開発** -- サーバーを独立して開発、テスト、バージョニング可能
- **柔軟な使用方法** -- 同一パッケージが開発サーバーとCIジェネレーターの両方を提供

REST APIエンドポイント、CLI引数、データ型、アーキテクチャの詳細については、[Doc History Serverリファレンス](https://zudo-doc.takazudomodular.com/ja/docs/reference/doc-history-server)を参照してください。