Next.js devサーバーでselect・ボタンが無反応になる症状の原因と診断
結論:「画面は動くのにUIが反応しない」はReactが起動していない
Next.js の dev サーバーで、以下のような症状が出たことはないでしょうか。
<select>を変えてもイベントが発火しない- ボタンをクリックしても何も起きない
- コンソールにエラーは出ていない(ように見える)
- ページをリロードしても同じ状態が続く
この症状の 真因は React のバグでも onChange の書き漏れでもなく、.next/static/chunks/ が空になっていること がほとんどです。クライアント側の JavaScript が一切ロードされず、SSR で生成した HTML が表示されているだけの「React が死んでいる」状態です。
3行サマリー:
.next/static/chunks/が空になると client JS がロードされず React が起動しない- ブラウザの console の 404 を見れば 1 分で診断できる
.nextディレクトリを削除してnpm run devを再起動するだけで復旧する
この記事の前提
Next.js App Router (Next.js 15系) で自作の SaaS ツール(issue-finder)を開発中に発生した実際のインシデントをもとに書いています。2026年5月17日に遭遇し、誤診を経て原因特定・復旧まで記録しました。
- 環境: Next.js 15 / App Router / TypeScript
- 症状の発生条件: dev サーバーを長時間起動したまま作業していた場合に発生しやすい
- 影響: UIのインタラクティブな操作が全滅(ただし SSR 部分の表示は正常)
最初の誤診パターン:「React の onChange バグ」
自作ツールのデバッグ中、ユーザーから「select を変えてもプロンプトが変わらない / コピーボタンが無反応」という報告を受けました。
最初に疑ったのは React の onChange ハンドラのバグ でした。
{/* こういうコードに問題があるんじゃないかと疑い始める */}
<select onChange={(e) => setSelected(e.target.value)}>
{options.map(opt => <option key={opt}>{opt}</option>)}
</select>
コードを読んでもおかしい部分が見当たらない。console.log を追加しても出力がない。「console.log が出ない」の一点で、これは JavaScript 自体が実行されていないのでは という気づきに至りました。
この誤診で費やした時間は約 15 分です。正しい診断アプローチは、React コードを読む前にブラウザの console を確認することでした。
実際に起きていたこと
ブラウザの開発者ツールを開いて Network タブを確認すると、以下のようなエラーが大量に出ていました。
GET /_next/static/chunks/main-app.js 404 Not Found
GET /_next/static/chunks/app-pages-internals.js 404 Not Found
GET /_next/static/chunks/pages/index.js 404 Not Found
.next/static/chunks/ 配下のファイルが全部 404 になっています。
ローカルの .next/static/chunks/ ディレクトリを確認すると、ディレクトリは存在しているが中身が空、もしくは buildId が変わっていてブラウザがキャッシュしている古い chunk ファイルを要求している状態でした。
ls .next/static/chunks/
# → ファイルがほとんどない、または空
原因:.next/static/chunks/ が空になる仕組み
Next.js の dev サーバーは、コード変更を検知して Hot Module Replacement (HMR) でリビルドします。このリビルドが何らかの理由で中断・失敗すると、古い chunks が削除された後に新しい chunks が生成されない「空の状態」が発生することがあります。
主な発生パターンは以下の 3 つです。
パターン 1: ファイル監視の暴走
fs.watch が特定の条件(外部プロセスによるファイル変更、シンボリックリンク等)で無限に発火し、リビルドが正常終了できない。
パターン 2: メモリ不足によるビルド失敗
長時間 dev サーバーを起動し続けると Node.js のヒープが増大し、chunks の生成中にクラッシュすることがあります。
パターン 3: 別プロセスとの競合
Playwright などのブラウザ自動化ツールが同時に動いている場合、ファイルシステムへのアクセスが競合してビルドが壊れることがあります。(注: Playwright のコンソールログ書き出しで HMR ループが起きるという別のインシデントもあります)
診断ステップ:console の 404 から始める
Step 1: ブラウザの console を開く
F12 → Console タブ または Network タブを開いて、_next/static/chunks/ の 404 エラーを確認します。
❌ GET /_next/static/chunks/main-app.js 404
→ React クライアントが未ロード確定
Step 2: ローカルの chunks ディレクトリを確認
ls -la .next/static/chunks/ | wc -l
# → 極端に少ない(正常時は数十ファイル)場合は空化している
Step 3: dev サーバーのターミナルを確認
# ターミナルに以下のようなエラーが出ているか確認
Error: ENOENT: no such file or directory, open '.next/...'
TypeError: Cannot read properties of undefined
Step 4(診断確定後): .next 削除 + dev 再起動
# ctrl+C で dev サーバーを止める
rm -rf .next
# 再起動
npm run dev
これだけで 1 分以内に復旧します。
再発防止策
根本的な解決は難しいですが、発生頻度を下げる対策です。
対策 1: dev サーバーを定期的に再起動する
8 時間以上連続稼働させない。長時間作業後は .next を削除してから再起動するを習慣化します。
対策 2: Playwright との競合を避ける
テスト実行中は dev サーバーと別ポートを使う、もしくはテスト用ビルド(next build + next start)を使います。
対策 3: package.json にクリーン再起動コマンドを追加する
{
"scripts": {
"dev": "next dev",
"dev:clean": "rm -rf .next && next dev"
}
}
症状が出たら npm run dev:clean 一発で済む状態にしておくと精神的ストレスが減ります。
診断フロー早見表
| 症状 | 最初に確認すること | 確認方法 |
|---|---|---|
| ボタン・select が無反応 | console 404 | DevTools → Network → JS |
| console.log が出ない | .next/chunks の状態 | ls .next/static/chunks/ |
| HMR が無限ループする | 外部プロセスの競合 | Playwright / ファイル監視 |
| SSR は正常、CSR だけ死んでいる | chunks ファイルの存在 | ls -la .next/static/ |
で、どう稼ぐ?
この症状の誤診で失う時間は、慣れるまで 1 症状あたり 15〜30 分 です。月に数回遭遇するとすれば、月 1〜2 時間が「知っていれば 1 分で解決できた問題」に消えています。
個人開発者にとって、デバッグの上手さはそのまま可処分時間の差になります。 Claude Code を使って開発速度を上げても、このような環境依存のトラブルで時間を溶かしていると実質的な生産性は上がりません。
masatoman.net では、このような「一次情報として踏んだトラップ」を中心に、Claude Code を使って個人開発で稼ぐための実践知識 を公開しています。
環境トラブルの解決パターンを体系化したい方、Claude Code の実運用でつまずきたくない方は、以下のニュースレターで最新の実験ログを受け取れます。
今日やること(3つ)
package.jsonにdev:cleanスクリプトを追加する — 症状が出たときの復旧コストを 0 にする- 次に「UIが反応しない」症状が出たら、コードを読む前に console の 404 を確認する — 誤診の時間を削る
- dev サーバーを長時間使っている場合は定期的に再起動する習慣をつける