# DevTools

組み込みのDevToolsパネルを使うと、開発中にブラウザから離れることなくアプリケーションの動作を検査できます。サーバープロセスの状態、RSCペイロードの内容、キャッシュの動作、ルートツリー、アウトレットのレイアウト、リモート/ライブコンポーネント、ワーカースレッド、サーバーログをカバーしています。

## DevToolsの有効化

開発サーバーの起動時に`--devtools`を渡します：

```sh
pnpm react-server ./App.jsx --devtools
```

または設定ファイルに追加して再起動時も維持されるようにします：

```js
// react-server.config.mjs
export default {
  devtools: true,
};
```

DevToolsは開発専用です。プロダクションビルドには含まれません。

## パネルを開く

有効にすると、右下にreact-serverのロゴが入った小さなフローティングボタンが表示されます。クリックするとパネルが開きます。キーボードショートカットも使えます：

| ショートカット | プラットフォーム |
|----------|----------|
| Ctrl+Shift+D | Windows / Linux |
| Cmd+Shift+D | macOS |

同じショートカットでパネルを閉じます。

## パネルの配置

パネル上部のツールバーに4つのドッキングモードボタンがあります。クリックしてパネルの位置を切り替えます：

-  **Bottom**（デフォルト）— パネルが下端にドッキングし、ページが垂直方向に縮小します。
-  **Left** /  **Right** — パネルが側面にドッキングし、ページが水平方向に縮小します。
-  **Float** — パネルがフリーフローティングウィンドウになり、ツールバーをドラッグして移動、右下のコーナーからリサイズできます。

ドッキングモードでは、パネルとページの間のハンドルをドラッグしてサイズを調整できます。

パネルの状態（開閉、ドッキングモード、サイズ、フロート位置）はすべて`localStorage`に保存され、ページリロード後も維持されます。

## ダークモード

ツールバーの  /  ボタンでライトモードとダークモードを切り替えます。DevToolsは以下の順序でアプリのテーマを自動検出します：

1. ``の`dark`または`light`クラス
2. `dark=1`または`dark=0` Cookie
3. システムの`prefers-color-scheme`メディアクエリ

トグルをクリックするとパネルとホストページの両方が更新され、Cookieで設定が保存されます。

## タブのオーバーフロー

パネルには9つのタブがあります。パネルの幅が狭くてすべて表示できない場合、収まらないタブはタブバーの右側にある  ボタンのオーバーフローメニューに折りたたまれます。現在アクティブなタブは、通常オーバーフローする場合でも常に表示されます。

## Statusタブ

Statusタブは開発サーバーのリソース使用状況を表示します。毎秒新しいデータをストリーミングする`"use live"`コンポーネントです。

3つのカードが表示されます：

| カード | 表示内容 |
|--------|----------|
| Process | Node.jsバージョン、PID、プラットフォーム/アーキテクチャ、稼働時間 |
| CPU | 使用率のゲージ（50%未満は緑、80%まで黄、それ以上は赤）、コア数、1/5/15分のロードアベレージ |
| Memory | ヒープ使用量/合計、RSS、外部メモリ、ArrayBuffers、OS全体のメモリ — 各メトリクスにゲージバー付き |

このタブで時間経過によるメモリの増加（リークの兆候）を監視したり、レンダリングの変更がCPUに負荷をかけていないか確認できます。

## Payloadタブ

Payloadタブはすべての React Server Components Flightレスポンスをキャプチャしてデコードし、サーバーが送信した内容を正確に確認できます。

### ページサイズバーの見方

タブの上部にある積み上げバーは、初期HTMLドキュメントを3つのセグメントに分解します：

| セグメント | 色 | 内容 |
|---------|-------|-----------------|
| RSC Payload | 緑 | HTMLに埋め込まれたFlightストリーム |
| Hydration | 紫 | クライアント用にインライン化された`"use cache"`エントリ |
| HTML | 青 | その他すべて（マークアップ、スクリプト、スタイル） |

合計サイズと転送サイズがバーの下に表示されます。転送サイズが小さい場合、サーバーがレスポンスを圧縮しています。

### ペイロードの選択

ドロップダウンにセッション中にキャプチャされたすべてのペイロードが表示されます。各エントリにはURL、合計バイトサイズ、チャンク数が表示されます。選択して検査します。

| ラベル | キャプチャ内容 |
|--------|---------------|
| ⚡ initial | 最初のページロードのFlightデータ |
| 🔄 stream | 初期レスポンスの後に到着した追加チャンク（Suspenseバウンダリを通じてストリーミング） |
| 🧭 nav | クライアントサイドナビゲーションで発生したFlightレスポンス |

### チャンクの検査

サマリーバッジの下に、すべてのFlightプロトコル行がチャンクリストとして表示されます：

| カラム | 意味 |
|--------|---------|
| ID | チャンク識別子 |
| Type | 色付きタグ：Model（コンポーネントツリーデータ）、Module（クライアントコンポーネントインポート）、Error、Hint（リソースプリロード）、Debug、Text、Binary、Console |
| Size | そのチャンクが占めるバイト数 |
| Data | チャンク内容の切り詰められたプレビュー |

フィルターフィールドにタグ名（例：`module`）やコンテンツの部分文字列を入力してリストを絞り込めます。

### ペイロード内のクライアントコンポーネントを見つける

**Client References**セクションを展開すると、サーバーが参照したすべての`"use client"`モジュールが表示されます。各エントリにはモジュールパスとエクスポート名が表示されます。参照にホバーすると、ページ上の対応するDOM要素が緑のオーバーレイでハイライトされます。参照をクリックすると、チャンクリストの対応するModuleチャンクにスクロールします。

## Cacheタブ

Cacheタブはサーバーとクライアントの両方で発生するすべての`"use cache"`呼び出しを記録し、ヒット、ミス、再検証のいずれかを表示します。

### キャッシュイベントの読み方

イベントリストの各行には以下が含まれます：

| カラム | 意味 |
|--------|---------|
| Time | 呼び出しが発生した時刻 |
| Type | `hit`（キャッシュから提供）、`miss`（計算して保存）、`revalidate`（バックグラウンドで再計算） |
| Provider | `request`（1リクエストのみ有効）または`default`（リクエスト間で永続） |
| Function | キャッシュされた関数名と呼び出し引数 |
| Source | ファイルパスと行番号 — クリックするとVS Codeで開く |
| TTL | ミスと再検証で表示。エントリの有効期間 |

ツールバーの上部にヒット/ミス/再検証の集計カウントが表示されます。フィルターボタンで1つのタイプのみ表示できます。

### キャッシュエントリの無効化

`default`プロバイダーのキャッシュイベントにホバーし、右側の  をクリックします。サーバー上のエントリが即座に無効化され、イベントリストから削除されます。その関数への次回の呼び出しはミスになります。リクエストスコープのキャッシュエントリはリクエスト終了時に破棄されるため、手動で無効化できません。

### ハイドレーションデータの確認

リクエストスコープのキャッシュで`"use cache"`を使用している場合、サーバーはそれらのキャッシュエントリをHTMLにシリアライズし、クライアントが再フェッチなしでハイドレーションできるようにします。Cacheタブの上部にある折りたたみ可能な**request cache**セクションに、ハッシュキー、バイトサイズ、シリアライズされたデータのプレビューとともに表示されます。

## Routesタブ

Routesタブはファイルシステムルーターが生成した完全なルートツリーを表示します。ページ、レイアウト、ミドルウェア、APIルート、エラーバウンダリ、ローディング状態、フォールバック、テンプレート、名前付きアウトレットがすべてリストされます。

### ルートのフィルタリング

| コントロール | 使い方 |
|-------------|--------|
| テキストフィルター | パスの断片、ファイル名、アウトレット名、HTTPメソッドを入力してリストを絞り込む |
| タイプボタン | タイプ（page、layout、middleware、api、error、loading、fallback、template、outlet）をクリックしてそのタイプのみ表示。各ボタンのカウントバッジにそのタイプのルート数が表示される |
| Activeトグル | 「active」をクリックすると、現在のサーバーパス名に一致しないものをすべて非表示にする。現在のURLのレンダリングに関与しているレイアウト、ミドルウェア、ページを正確に確認するのに便利 |

### アクティブルートの理解

現在のサーバーパス名に一致するルートは緑の左ボーダーでハイライトされます。マッチングは動的セグメント（`[param]`）、オプショナルパラメータ（`[[optional]]`）、キャッチオールパターン（`[...slug]`）を考慮します。レイアウト、ミドルウェア、テンプレートはプレフィックスとしてマッチし（すべての子パスに対してアクティブ）、ページは正確にマッチする必要があります。

> 注意：マッチングに使用されるパス名はクライアントに表示されるURLではなく、**サーバーパス名**（リライト適用後）です。

### ソースファイルを開く

各ルート行にはファイルタイプアイコン（React/JSX、TypeScript、MDXなど）と相対ソースパスが表示されます。ソースパスをクリックするとVS Codeでファイルが開きます。

### コンポーネントルート

ファイルルーターツリーの下に、コード内の``コンポーネントでルートを登録している場合、**Component Routes**セクションが表示されます。各エントリにはルートパターン、タイプ（server、client、fallback）、`remote`、`exact`、`loading`などのフラグが表示されます。アクティブなコンポーネントルートはマッチしたパスパラメータがインラインで表示されます。

## Outletsタブ

Outletsタブはページ上に現在レンダリングされているすべての名前付きアウトレットを一覧表示します。アウトレットとは、レイアウトがpropsとして受け取る名前付きスロット（`@sidebar`、`@content`など）と、ルートのレンダリングスロットである`PAGE_ROOT`です。

### 各アウトレットカードの表示内容

| フィールド | 意味 |
|-----------|---------|
| Name | アウトレット識別子 |
| URL | アウトレットコンテンツのロード元URL（該当する場合） |
| Badge | アウトレットの管理方法：`router`（ファイルルーター）、`remote`（別のサーバーから取得）、`island`（Hydration Island）、`live`（ストリーミング）、`defer`（遅延ロード）、`static`。Hydration Island には `hydrated` または `not hydrated` も表示され、すでにインタラクティブになっているかどうかを確認できます。 |

### ページ上のアウトレットをハイライトする

任意のアウトレットカードにホバーします。ページ上のそのアウトレットのレンダリング領域の周りに、アウトレット名のラベル付きの色付き破線の矩形が表示されます。各アウトレットに異なる色が割り当てられるので、カードとページのセクションを視覚的にマッピングできます。

ハイライトオーバーレイはエッジケースも処理します：隠しマーカー要素、複数の兄弟要素としてレンダリングされるアウトレット（オーバーレイはユニオン境界矩形をカバー）、フルスクリーンのバックドロップ要素（実際のコンテンツがハイライトされるようにフィルタリング）。

### スクロールとリフレッシュ

| アクション | 動作 |
|-----------|------|
|  | ページをアウトレットの位置にスクロールする |
|  | ページ全体をリロードせずにそのアウトレットのみを再レンダリングする — ナビゲーションせずにページの一部分のサーバーサイドの変更をテストしたい場合に便利 |

## Remotesタブ

アプリが``を使って他のreact-serverインスタンスからRSCコンテンツをロードしている場合、Remotesタブに各コンポーネントが表示されます。

各カードには以下が表示されます：

| フィールド | 意味 |
|-----------|---------|
| リモートURL | コンポーネントの取得元URL。 をクリックして新しいブラウザタブで開ける |
| アウトレット名 | このリモートコンポーネントがレンダリングされるアウトレット |
| TTLバッジ | レスポンスのキャッシュ期間 |
| `isolate`バッジ | コンポーネントがサンドボックスでレンダリングされる |
| `defer`バッジ | コンポーネントが遅延ロードされる |
| `live`バッジ | コンポーネントがリアルタイム更新をストリーミングする |

ホバーするとページ上のリモートコンポーネントがハイライトされます。 をクリックしてスクロール、 をクリックしてOutletsタブのアウトレットにジャンプします。

## Liveタブ

Liveタブはすべての`"use live"`コンポーネント — クライアントに連続的なレンダリングをyieldするサーバー上の非同期ジェネレーター関数 — を監視します。

各カードにはコンポーネントの名前、現在の状態、ランタイム統計が表示されます：

| 状態 | 意味 |
|-------|---------|
| `starting` | ジェネレーターを初期化中 |
| `waiting` | 次のyieldまで待機中 |
| `running` / `connected` | クライアントにアクティブにストリーミング中 |
| `finished` | ジェネレーターが正常に終了 |
| `aborted` | クライアントが切断 |
| `error` | ジェネレーターが例外をスロー（エラーメッセージがインラインで表示） |

データ送信中は`streaming`バッジが表示されます。カードにはジェネレーターのyield回数、最後のyield時刻、コンポーネントの開始時刻も表示されます。リモートサーバーからロードされたコンポーネントには`remote`バッジが表示されます。

## Workersタブ

Workersタブは`"use worker"`スレッド — サーバーサイドのWorker Threads（Node.js）とクライアントサイドのWeb Workers — を追跡します。

ツールバーにワーカーの総数がタイプ別の内訳とともに表示されます。フィルターボタンでサーバーまたはクライアントのワーカーのみを表示できます。

各ワーカーエントリには以下が表示されます：

| フィールド | 意味 |
|-----------|---------|
| Type | `server`または`client` |
| State | `Spawning`（スレッド起動中）、`Ready`（アイドル）、`Error`（最後の呼び出しが失敗）、`Restarting` |
| Module path | ワーカーを定義するファイル。最後のいくつかのパスセグメントに短縮される |
| Call count | 合計呼び出し数と現在実行中の数 |
| Error / restart counts | 不安定なワーカーを発見するため |
| Last function | 最後に呼び出されたエクスポート関数の名前 |
| Timing | ワーカーのスポーン時刻と最終呼び出し時刻 |

## Logsタブ

Logsタブはすべてのサーバーターミナル出力（`stdout`と`stderr`）をブラウザにストリーミングするので、ターミナルに切り替える必要がありません。

### ログのフィルタリング

| コントロール | 使い方 |
|-------------|--------|
| ストリームボタン | `stdout`または`stderr`をクリックしてそのストリームのみ表示する。各ボタンのカウントにそのタイプのエントリ数が表示される |
| 検索フィールド | テキストを入力してログエントリをフィルタリングする。検索はANSIコードを除去したプレーンテキストに対してマッチする |

### ANSI出力の表示

サーバーログには色やテキストスタイリングのためのANSIエスケープコードが含まれることがよくあります。Logsタブはこれらを忠実にレンダリングします — 4ビット、8ビット、24ビット（トゥルーカラー）シーケンスがすべてサポートされ、太字、イタリック、下線、薄字も含まれます。パネルに表示される内容はターミナルで見えるものと同じです。

### 自動スクロールの動作

デフォルトではログビューは最下部に固定され、新しいエントリが到着するとスクロールします。上にスクロールすると自動スクロールが一時停止します。パネルの下部に**Scroll to bottom**ボタンが表示されます — クリックして再開します。

ツールバーの**Clear**をクリックしてログバッファを空にします。

## 要素ハイライト

いくつかのタブでは、アイテムにホバーしてページ上の対応する要素をハイライトできます：

- **Payload**タブで、クライアント参照にホバーすると、そのクライアントコンポーネントがレンダリングしたDOM要素がハイライトされます（緑のオーバーレイ）。
- **Outlets**タブで、アウトレットカードにホバーすると、そのレンダリング領域がハイライトされます（各アウトレットに固有の色）。
- **Remotes**タブで、リモートカードにホバーすると、同じ方法でレンダリング領域がハイライトされます。

オーバーレイは名前を示すラベルバッジ付きの色付き破線の矩形です。ページをスクロールやリサイズするとリアルタイムで位置が更新されます。

## DevToolsの仕組み

パネルUIは`/__react_server_devtools__/*`から提供されるiframe内で実行されます。これによりDevToolsのReactツリーがアプリから分離され、コンポーネントの状態やスタイリングに干渉しません。

3つの通信チャネルが各部分を接続します：

- **ホストページ → Iframe**（`postMessage`）：RSCペイロード（`fetch`のインターセプトによりキャプチャ）、アウトレット登録、コンポーネントルート、ページレベルのサイズ統計、ナビゲーションイベント、テーマ変更。
- **サーバー → Iframe**（Socket.IO、`/__devtools__`ネームスペース）：ライブコンポーネントの状態、サーバーサイドのキャッシュイベント、ワーカーの状態、サーバーログ、ファイルルーターマニフェスト。パネルが開くと自動的に接続が確立されます。
- **Iframe → サーバー**（Socket.IO）：キャッシュ無効化リクエストとアウトレットリフレッシュコマンドが同じソケットを通じて送信されます。