【対処法】Next.js開発で発生するハイドレーションエラーの原因と解決策

ReactやNext.jsで開発していると、一度は遭遇するであろうハイドレーションエラー。
見た目には問題ないのに、コンソールにエラーが出て不安になる…そんな経験はありませんか?
ハイドレーションエラーは、サーバーサイドレンダリング(SSR)とクライアントサイドの描画結果に差異がある場合に発生します。
本記事では、そのメカニズムと原因、そして再発させないための具体的な対策を、初心者にもわかりやすく整理しました。
ハイドレーションエラーの発生原因
ハイドレーションとは、SSRで描画されたHTMLに対してクライアント側でReactがイベントバインドなどを行うプロセスのこと。
この際、サーバーで生成されたHTMLとクライアントでのJSによる描画結果が一致しない場合に、次のようなエラーが出力されます。
arduinoWarning: Text content did not match. Server: "Hello" Client: "Hi"
原因となる具体例は以下の通りです:
原因 | 説明 | 例 |
---|---|---|
クライアント限定APIの使用 | window やnavigator など、SSR時に存在しないオブジェクトを利用 | useEffect 外でwindow.innerWidth を参照 |
ランダム値の使用 | SSRとCSRで異なる値になる | Math.random() やDate.now() の直接使用 |
状態の非同期取得 | クライアントでのみデータを取得してUIを更新する | 初期表示がloading 、CSR後にデータ になる差異 |
時刻やロケールに依存 | タイムゾーンやIntl により描画が変化 | 日付のローカライズ表示など |
ハイドレーションエラーを防ぐための対策
ハイドレーションエラーを避けるためには、サーバーとクライアントで同じHTMLを出力することが鉄則です。
以下に具体的な対策を紹介します。
1. クライアント限定処理はuseEffect
内に記述
ReactのuseEffect
はクライアント実行時のみ動作します。
window
などのブラウザAPIを使用する場合は、必ずこの中で処理しましょう。
tsxconst [width, setWidth] = useState(0);
useEffect(() => {
setWidth(window.innerWidth);
}, []);
2. ランダム・時刻系の値はSSR側でも揃える
例えばDate.now()
を直接使わず、getServerSideProps
やgetStaticProps
で生成し、Propsとして渡すようにします。
tsxexport const getServerSideProps = () => {
return {
props: {
timestamp: Date.now(),
},
};
};
3. dynamic()
を使ってクライアントのみレンダリング
どうしてもSSRで描画したくないコンポーネントは、next/dynamic
でクライアント限定に。
tsximport dynamic from 'next/dynamic';
const ClientOnlyComponent = dynamic(() => import('./ClientOnlyComponent'), {
ssr: false,
});
4. 条件付きレンダリングで安全確認
typeof window !== "undefined"
のようなチェックを使い、SSR時の実行を防ぐ工夫も効果的です。
tsx{typeof window !== "undefined" && <ClientOnlyComponent />}
まとめ:Next.jsではSSRとCSRの一貫性が鍵
ハイドレーションエラーは、見た目に影響が出ないことも多いため軽視されがちですが、SEOやパフォーマンス、アクセシビリティに悪影響を与える可能性があります。
ハイドレーションの原理と原因を正しく理解し、以下のポイントを抑えて開発を進めましょう。
- SSRとCSRで出力を一致させる
- クライアント専用処理は
useEffect
へ - 不安定な値(日時、乱数、ブラウザAPI)はSSR中に扱わない
dynamic()
でSSRを明示的に制御
これらを意識するだけで、Next.jsでの開発がより安定し、安心してスケールするアプリケーションを構築できます。
- article
NestJS と GraphQL を組み合わせた型安全な API 開発
- article
【実践】NestJS で REST API を構築する基本的な流れ
- article
NestJS でのモジュール設計パターン:アプリをスケーラブルに保つ方法
- article
【入門】NestJS とは?初心者が最初に知っておくべき基本概念と特徴
- article
Prisma と NestJS を組み合わせたモダン API 設計
- article
TypeScript で学ぶミドルウェア設計パターン:Express・NestJS の応用例
- article
Electron 入門 2025:Web 技術でデスクトップアプリを作る全体像
- article
Claude Code 概要とユースケース地図:個人開発からエンタープライズ導入まで一望
- article
Redis 基礎 速習:データ構造と単一スレッドの仕組みを図解で理解
- article
Ansible 入門 2025年:5 分で分かる自動化の全体像と始め方
- article
MySQL オプティマイザ概説:実行計画が決まるまでの舞台裏
- article
Zustand を React なしで使う:subscribe と Store API だけで組む最小構成
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来