Next.jsの開発中に発生する Warning: Prop `className` did not match. Server: Client: ...の解決策
Next.js の開発中に 発生する Warning: Prop className did not match. Server: "vsc-initialized" Client: "" Error Component Stack の警告の解決策について紹介いたします。
“Prop className did not match” は、Video Speed Controller(VSC)というブラウザ拡張が <body> へ自動付与する vsc-initialized クラスが原因です。
SSR で生成された HTML にこのクラスが無い一方、クライアント側では拡張が先にクラスを追加するため水和(Hydration)時に差分が発生します。
まずは VSC が混入元であることを確認した上で、開発・運用フェーズ別に現実的な対処を行いましょう。
原因要素の特定
vsc-initialized は Visual Studio Code ではなく Video Speed Controller 拡張が注入する識別子です。本番ユーザーが同拡張を入れていても水和前にクラスが追加されることは稀ですが、開発中はローカルサーバーの応答より拡張スクリプトの実行が速く、警告が顕在化します。
再現条件
| # | 条件 | 説明 |
|---|---|---|
| 1 | 開発コマンド (next dev) 利用 | ローカルでの開発時に発生する |
| 2 | VS Code 拡張機能が有効 | body.classList.add('vsc-initialized') を実行 |
| 3 | <body> に Tailwind などのユーティリティクラスをバインド | Server → Client で文字列比較される |
エラー内容(全文)
javahook.js:608 Warning: Prop `className` did not match. Server: "vsc-initialized" Client: "" Error Component Stack
at body (<anonymous>)
at html (<anonymous>)
at RedirectErrorBoundary (redirect-boundary.js:73:9)
at RedirectBoundary (redirect-boundary.js:81:11)
at NotFoundErrorBoundary (not-found-boundary.js:76:9)
at NotFoundBoundary (not-found-boundary.js:84:11)
at DevRootNotFoundBoundary (dev-root-not-found-boundary.js:33:11)
at ReactDevOverlay (ReactDevOverlay.js:84:9)
at HotReload (hot-reloader-client.js:307:11)
at Router (app-router.js:181:11)
at ErrorBoundaryHandler (error-boundary.js:114:9)
at ErrorBoundary (error-boundary.js:161:11)
at AppRouter (app-router.js:536:13)
at ServerRoot (app-index.js:129:11)
at RSCComponent (<anonymous>)
at Root (app-index.js:145:11)
対策一覧
| # | 手順 | 詳細 | 効果 |
|---|---|---|---|
| 1 | VSC を無効化 | Chrome アドレスバー → chrome://extensions/ → Video Speed Controller を OFF | 根本的に警告を除去 |
| 2 | 開発専用プロファイル | 新規ブラウザプロファイルを作成し拡張をインストールしない | 拡張を残したまま安全に開発 |
| 3 | インライン同期スクリプト | _document.tsx の <body> 直後に下記を挿入 | 水和前にクラスを同期し警告を防止 |
インライン同期スクリプト の実装例(Next.js App Router)
tsx// app/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head />
<body className="bg-on-background">
{/* dev 環境のみクラス同期 */}
<script
dangerouslySetInnerHTML={{
__html: `(function(){
try{
if(location.hostname==='localhost' && !document.body.classList.contains('vsc-initialized')){
document.body.classList.add('vsc-initialized');
}
}catch(e){}
})();`,
}}
/>
<Main />
<NextScript />
</body>
</Html>
)
}
- インラインスクリプトは
<NextScript />より前に置くことで React ハイドレーションより先に実行 されます。 localhost判定で本番ビルドに影響しないよう限定します。- Tailwind 使用時にパージ対象外へしたい場合は
tailwind.config.jsにsafelist: ['vsc-initialized']を追加すればスタイル損失を防げます。
本番環境向けチェックリスト
| # | 確認項目 | コマンド/設定 | 目的 |
|---|---|---|---|
| 1 | 本番ビルド検証 | yarn build && yarn start | 警告が出ないことを確認 |
| 2 | CSP ヘッダー | Content-Security-Policy: script-src 'self' | 拡張スクリプトの早期実行を抑制 |
| 3 | 早期クラス付与 | 先述の _document.tsx スクリプト | 拡張ありユーザーでも差分ゼロ |
まとめ
最適解は 開発ブラウザから Video Speed Controller を切り離す ことです。
どうしても無効化できない事情がある場合は、_document.tsx 内でサーバー・クライアントのクラスを同期させ、水和前の DOM 差分を解消してください。suppressHydrationWarning は緊急避難策に過ぎませんので、恒久対応としては拡張の影響範囲を明確に隔離する設計を推奨いたします。
関連リンク
articleNext.js の Route Handlers で multipart/form-data が受け取れない問題の切り分け術
articleNext.js Server Components 時代のデータ取得戦略:fetch キャッシュと再検証の新常識
articleNext.js の 観測可能性入門:OpenTelemetry/Sentry/Vercel Analytics 連携
articleNext.js でドキュメントポータル:MDX/全文検索/バージョン切替の設計例
articleNext.js でインフィニットスクロールを実装:Route Handlers +`use` で滑らかデータ読込
articleRedis 使い方:Next.js で Cache-Tag と再検証を実装(Edge/Node 両対応)
articleNotebookLM 活用事例:営業提案書の下書きと顧客要件の整理を自動化
articleGrok RAG 設計入門:社内ドキュメント検索を高精度にする構成パターン
articlegpt-oss 運用監視ダッシュボード設計:Prometheus/Grafana/OTel で可観測性強化
articleNode.js 標準テストランナー完全理解:`node:test` がもたらす新しい DX
articleNext.js の Route Handlers で multipart/form-data が受け取れない問題の切り分け術
articleMCP サーバー で社内ナレッジ検索チャットを構築:権限制御・要約・根拠表示の実装パターン
blogiPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
blogGoogleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
blog【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
blogGoogleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
blogPixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
blogフロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
review今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
reviewついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
review愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
review週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
review新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
review科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来