Next.jsを上げた直後に、開発画面で hydration mismatch が急に増えて「どこから触ればいいんだろう」と止まること、ありますよね。この記事は、Next.js 16.2とTypeScript 6.0移行を同時に進める人に向けて書いています。読むと、+ Client / - Server の差分表示を使って、原因特定から修正までを最短で回せるようになります。僕は福祉事業のIT全般を担当しながら、AI×SaaSの開発も並行していて、実務でこの手の初期表示トラブルを潰し続けています。その経験を、今日から使える形でまとめます。
公開前確認(2026年5月時点):Next.js 16.2系とTypeScript 6移行では、Hydration mismatchを型エラーだけで扱わず、SSR/CSR差分、日付・乱数、ブラウザ専用API、依存パッケージの順に切り分けてください。
こんな方におすすめ
- Next.js 16.2へ上げたら hydration mismatch が増えた方
- TypeScript 6.0移行で
tsconfigの差分に不安がある方 - SSR/CSRの不一致を毎回感覚で直してしまう方
- チームで再発防止のルールまで作りたい方
この記事でわかること
- Hydration Diff Indicator の読み方と切り分け順
- TS6移行で不一致が顕在化しやすい理由
- 最短で直す10項目チェックリスト
- 再発を減らすCI・レビュー観点
- 1 Next.js 16.2のHydration差分表示とは何か(+ Client / – Serverの読み方)
- 2 TypeScript 6.0移行で不一致が増える理由(baseUrl・moduleResolution変更の影響)
- 3 最短で直すチェックリスト10項目(原因7分類+優先修正順)
- 4 差分表示を使った実戦デバッグ手順(再現→切り分け→修正→再検証)
- 5 そのまま使える修正コード集(useEffect / dynamic ssr:false / suppressHydrationWarning / iOS対策)
- 6 再発防止のCI・レビュー観点(tsconfig監査、SSR初期描画の固定化、Edge/CDN設定)
- 7 TypeScript 6.0移行を後回しにした先に待つ現実
- 8 この記事を書いている理由
- 9 次のアクション
Next.js 16.2のHydration差分表示とは何か(+ Client / – Serverの読み方)
2026年3月18日に公開された Next.js 16.2 で、Hydration Diff Indicator が入りました。エラーオーバーレイ上で、サーバー出力とクライアント出力の差分が + Client / - Server で並ぶので、以前より「どこがズレたか」を直接見つけやすいです。公式リリースは Next.js 16.2 の紹介ページ で確認できます。
イメージとしては、Gitの差分をUIにそのまま出してくれる感じです。結論から言うと、まず差分の“種類”を読むだけで、修正方針の8割が決まります。例えば、日時文字列のズレなら Date() 系、タグ構造のズレなら不正ネスト、要素の有無が変わるなら window 分岐や browser API 依存を疑う、という流れです。
- 文字列だけ違う :
Dateやロケール、乱数、翻訳タイミングを確認します - 要素数が違う :
typeof windowや条件分岐、拡張機能の注入を疑います - DOM構造が違う :
<p>内に<div>を入れるなどの不正ネストを確認します
さらにこの版では Error.cause が最大5階層までオーバーレイに出るので、ライブラリ内部で起きた例外も追いやすいです。つまり「何が起きたか」を推測で埋める時間が減ります。差分を見る→原因を仮説化→最小修正で再検証 のループを、まず1日で習慣化すると強いです。
TypeScript 6.0移行で不一致が増える理由(baseUrl・moduleResolution変更の影響)
2026年3月23日の TypeScript 6.0 では、baseUrl の扱いが実質的に後退し、moduleResolution classic も終了しました。詳しくは TS 6.0 リリースノート にまとまっています。これ自体は良い整理ですが、移行時に import 解決の曖昧さが表面化し、SSR/CSRで別コードが通ってしまっていた箇所が露出しやすいです。
| 論点 | 移行前に起きがち | TS6移行後の変化 | Hydrationへの影響 |
|---|---|---|---|
| baseUrl依存 | 短いimportが偶然解決 | pathsを明示する流れへ | 実行時経路のズレが見える |
| classic解決 | 古い探索順が残る | modern前提へ統一 | 環境差の潜伏バグが減る |
| モノレポ参照 | 境界が曖昧 | 参照ルールを固定化 | SSR専用/CSR専用の混入を検知しやすい |
実務では、次のような差分から始めると安全です。
// before
"baseUrl": "./src",
"paths": {
"@app/*": ["app/*"]
}
// after
"paths": {
"@app/*": ["./src/app/*"]
}
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
最短で直すチェックリスト10項目(原因7分類+優先修正順)
Next公式のHydrationエラー解説は原因を7分類しています。ここに現場で効率が上がる3項目を足して、10項目チェックリストにしておくと迷いません。つまり「毎回ゼロから考えない仕組み」を作るということです。公式ページは こちら です。
- 不正ネスト確認 :
<p>内の<div>などHTML構造エラーを直します window分岐確認 : render中のtypeof window分岐を除去します- browser API確認 :
localStorage参照をクライアント実行へ寄せます - 日時・乱数確認 :
Date()Math.random()を初期描画から外します - 拡張機能影響確認 : シークレットモードで再現性を比較します
- CSS-in-JS設定確認 : 公式例通りにSSR設定を揃えます
- Edge/CDN改変確認 : HTML minifyや変換を無効化して検証します
- 差分表示の行番号記録 : 修正前後でスクショを残します
- 修正パターン選定 :
useEffect/dynamic ssr:false/ warning抑制を選びます - 再検証 : ハードリロードと別端末で初期表示を確認します
優先順位のコツ
- 最初に「DOM構造の不一致」を潰すと、連鎖エラーが一気に減ります
- 次に「日時・乱数」を固定すると、再現テストの精度が上がります
- 最後に
suppressHydrationWarningを検討すると、逃げ道の乱用を防げます
この順で回すだけで、調査時間が半日から1時間台に落ちるケースは珍しくないです。チーム全員で同じ順序を使うと、レビュー速度まで上がります。
差分表示を使った実戦デバッグ手順(再現→切り分け→修正→再検証)
ここからは、僕が実務で使っている30〜45分のデバッグ手順です。Next.js 16.2 は next dev の起動が約400%高速化、条件比較で Time-to-URL が約87%改善と説明されていて、試行回数を稼ぎやすいです。描画速度も実アプリで25〜60%改善の報告があるので、修正ループに向いています。
- 再現を固定 : ブランチを切り、エラー画面とURLを保存します
- 差分を分類 :
+ Client/- Serverを「文字列/要素/構造」に分けます - 最小修正 : 1箇所だけ直して再起動せずに即確認します
- 副作用確認 : イベント発火と入力フォームの挙動を触って確認します
- 再発防止メモ : 原因・修正・再発条件をPRテンプレに残します
// 例: まずは原因観測を優先
console.log('server-render-value', value)
useEffect(() => {
console.log('client-render-value', value)
}, [value])
ポイントは「一度に一つだけ変える」ことです。2つ以上を同時に直すと、どの変更が効いたかが分からなくなります。優先順位が割れたら、差分の種類ごとに担当を分けて30分で再集合する運用にすると、議論が止まりにくいです。
そのまま使える修正コード集(useEffect / dynamic ssr:false / suppressHydrationWarning / iOS対策)
公式が推奨している修正は大きく3つです。React公式でも「不一致はバグとして扱う」と明記されているので、まず正攻法で直します。suppressHydrationWarning は便利ですが、1階層のみの逃げ道なので常用はおすすめしません。
| 修正パターン | 向いている場面 | メリット | 注意点 |
|---|---|---|---|
| useEffectへ寄せる | クライアントだけで良い表示 | 安全で再発しにくい | 初期表示はプレースホルダ設計が必要 |
| dynamic ssr:false | 重いUI部品や外部依存 | 局所的に切り離せる | SEO対象領域には不向き |
| suppressHydrationWarning | 時刻など不可避差分 | 短期回避ができる | 根本原因は残る |
// 1) クライアント専用処理に寄せる
const [isClient, setIsClient] = useState(false)
useEffect(() => setIsClient(true), [])
// 2) 局所的にSSRを無効化
const NoSSR = dynamic(() => import('../components/no-ssr'), { ssr: false })
// 3) 不可避差分を抑制(1階層のみ)
<time suppressHydrationWarning />
// 4) iOS自動リンク化対策
<meta name="format-detection" content="telephone=no, date=no, email=no, address=no" />
イメージとしては、useEffect は「営業時間外の処理を後ろに回す」、dynamic ssr:false は「別レーンに流す」、suppressHydrationWarning は「一時的な注意書き」です。第一候補は常に useEffect からと覚えておくと判断が速くなります。
再発防止のCI・レビュー観点(tsconfig監査、SSR初期描画の固定化、Edge/CDN設定)
修正より大事なのは再発防止です。特にTS6移行期は tsconfig の差分が大きいので、設定監査をCIに載せるだけで事故率が下がります。僕の現場では、Node.js + TypeScript のモノレポで「初期描画は純粋関数に近づける」を合言葉にしています。
- tsconfig監査 :
baseUrl依存が残っていないかPRで確認します - SSR固定化 : 初回描画で
Daterandomwindowを使わない規約を置きます - Edge/CDN監査 : HTML変換・自動最適化の有効範囲を明示します
- レビュー定型文 : 「SSRとCSRで同じ出力か」をチェック項目に入れます
# 例: CIで最低限回す項目
npm run typecheck
npm run lint
npm run test
npm run build
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
TypeScript 6.0移行を後回しにした先に待つ現実
移行を先送りすると、普段は見えないズレがリリース直前に一気に噴き出す可能性があります。特に hydration mismatch は「見た目が少し違う」だけで終わらず、イベントが別要素に結びつくなどUX事故につながります。この仕組みを知らないままだと、開発速度だけでなくユーザー体験まで落ちる可能性があります。小さく直して、早く検証する習慣が結果的に一番コストを抑えます。
この記事を書いている理由
僕自身、ディズニーテーマの結婚式Web招待状サービスを継続改善して、90日以上のログイン継続率を作ってきました。初期表示で違和感が出ると、ユーザーは一瞬で離れるんですよね。だからこそ、Hydration不一致は「あとで直す不具合」ではなく「最初に潰す体験課題」だと強く感じています。福祉事業のIT全般を担当しながら、AI×SaaS開発でも同じ壁に何度も当たったので、実務で使える手順として残したいと思って書きました。
次のアクション
まずは今日、1つの画面でチェックリスト10項目を回してみてください。詰まった箇所をコメントやSNSで共有してくれたら、次の記事で具体例として深掘りします。
今日からできるアクション
- Next.js 16.2 の差分表示で、直近エラー1件を分類する
- TS6移行PRに「SSR/CSR一致チェック」を1行追加する
- 運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。