Back to blogs

How to Fix Hydration Mismatch Error in Next js?

April 9, 2025
4 min read
How to Fix Hydration Mismatch Error in Next js?

Hydration errors are among the most frustrating issues developers face when working with Next.js.


One moment your app runs fine during development, and the next, you see warnings like:


Warning: Text content did not match. Server: "Hello" Client: "Hi"


These hydration mismatches can break the seamless user experience, hurt SEO, and make debugging a nightmare.


In this guide, we'll explore what hydration errors are, why they occur, common scenarios, and practical ways to fix them.


What is a Hydration Error?


In Next.js (and React in general), hydration is the process where React takes over the static HTML generated by the server and attaches event listeners and dynamic functionality on the client side.


This ensures your app is interactive immediately after the page loads.


A hydration error occurs when there's a mismatch between what was rendered on the server (Server-Side Rendering or SSR) and what React expects on the client during hydration.


The DOM must be identical on both ends. Any discrepancy leads to hydration warnings or errors.


Common Causes of Hydration Mismatches


1. Non-Deterministic Rendering (Random Values)


If your component uses Math.random() or Date.now() during SSR, the output will differ between server and client.


// Problematic
function RandomComponent() {
const randomNumber = Math.random();
return <div>{randomNumber}</div>;
}


2. Client-Specific APIs or Window Access


Accessing window, localStorage, or other browser-only objects on the server will break hydration.


// Problematic
function ScreenWidth() {
const width = window.innerWidth;
return <p>Screen width is {width}</p>;
}


3. Time-Sensitive Content


Displaying current time, countdowns, or live data without synchronization.


// Problematic
function Clock() {
const now = new Date().toLocaleTimeString();
return <div>{now}</div>;
}


Fixes & Workarounds


1. Conditional Rendering with

useEffect


useEffect only runs on the client after hydration. This makes it a safe space to use browser-only APIs.


// Fixed using useEffect
import { useState, useEffect } from 'react';

function ScreenWidth() {
const [width, setWidth] = useState(null);

useEffect(() => {
setWidth(window.innerWidth);
}, []);

if (width === null) return null;
return <p>Screen width is {width}</p>;
}


2. Dynamic Imports with ssr: false


Next.js lets you load components only on the client using dynamic imports.


// Fixed with dynamic import
import dynamic from 'next/dynamic';
const NoSSRComponent = dynamic(() => import('../components/RandomComponent'), {
ssr: false,
});

export default function Page() {
return <NoSSRComponent />;
}


3. Client-Only Components


Wrap sensitive logic in a "ClientOnly" component that renders children after hydration.


// components/ClientOnly.js
import { useEffect, useState } from 'react';

export default function ClientOnly({ children }) {
const [hasMounted, setHasMounted] = useState(false);

useEffect(() => {
setHasMounted(true);
}, []);

if (!hasMounted) return null;
return children;
}


Usage:


import ClientOnly from '../components/ClientOnly';

function Clock() {
const now = new Date().toLocaleTimeString();
return <div>{now}</div>;
}

export default function Page() {
return (
<ClientOnly>
<Clock />
</ClientOnly>
);
}


4. Guarding Code with typeof window


You can also prevent SSR issues by wrapping code that accesses browser APIs.


function IsBrowser() {
if (typeof window === 'undefined') return null;
return <p>Running on client</p>;
}


Best Practices to Avoid Hydration Issues


1. Avoid Side Effects in Render

Never run side effects (like logging, timers, or fetching data) directly inside your render method.


2. Consistent Server & Client Output

Ensure that any code rendered both on the server and client produces the same output.


3. Use useEffect Wisely

Always move browser-dependent logic into useEffect or useLayoutEffect.


4. Be Mindful with Third-Party Libraries

Some UI libraries manipulate the DOM in unexpected ways. Wrap them in dynamic() with ssr: false if needed.


5. Keep Server Logic Pure

Make sure the server-side rendered components don’t depend on variables that change per client unless fetched explicitly.


Conclusion

Hydration errors in Next.js can be intimidating at first, but they’re easily manageable with the right patterns. Always remember: what the server sees,


The client should see too—until it hydrates. Whether you use useEffect, dynamic imports, or client-only components, the key is to isolate browser-only logic from the SSR process.


By following these guidelines, you'll not only fix hydration issues but also build more robust, predictable, and performant Next.js applications.


If this guide helped you, checkout my other blogs https://www.jigsdev.xyz/blogs/nextjs-performance-optimization

next js hydration errorhydration error reactnext js text content does not matchreact hydration mismatchhydration failed because the initial ui does not matchfix hydration error nextjshydration issue in next jshow to fix hydration error in react