ViteベースのStorybookではServer Componentのサーバー専用依存を再現できない — 表示ロジックをprops注入可能に分離する
Next.js
React
Storybook
知識
判断
Next.js App Router の async Server Component は、サーバー側のレンダリング基盤を持たない Vite ベースの Storybook やブラウザテスト環境では、そのままクライアントコンポーネントとして描画できない。
async 関数が純粋なデータ加工と JSX の組み立てだけを行う場合は、Storybook の loader などで関数を先に評価し、返された要素を同期的に描画できることがある。ただし、これは Server Component の実行環境を再現するものではなく、単なる async 関数として評価する迂回である。
コンポーネントが cookies、headers、サーバー専用の翻訳取得など、Next.js のサーバーランタイムや React Server Components 境界に依存している場合、この迂回では解決しない。クライアント描画環境から呼べない API は、loader 内から呼んでも同じ制約を受ける。
判断基準
- async であっても内部が純粋な計算と表示だけなら、事前評価による描画を試す余地がある。
- サーバー専用 API を呼ぶ場合は、Storybook 側の設定で再現しようとせず、サーバー処理と表示部分を分離する。
- コンポーネント本体を変更できず、サーバー依存も除けない場合は、無理にストーリー化せず対象外とする。
推奨構造
サーバー側コンポーネントはデータ取得と環境依存処理を担当し、その結果を props として同期的な表示コンポーネントへ渡す。Storybook では表示コンポーネントだけを固定データで描画する。これにより、Server Component の実行環境を模倣せずに視覚状態と操作を検証できる。
検証
最小ストーリーで実際に描画し、失敗が async コンポーネントのクライアント実行によるものか、個別のサーバー専用 API によるものかをエラーから切り分ける。表示部分へ分離した後は、ブラウザテストで描画と操作を確認し、サーバー側のデータ取得は別の統合テストで検証する。