Introduction

Hydration mismatch errors are common in React and even more common in Next.js, where server-side rendering (SSR) and client-side rendering must match perfectly.
You may have seen this error:

Warning: Text content does not match server-rendered HTML.

or

Hydration failed because the initial UI does not match what was rendered on the server.

This error means the HTML generated on the server differs from the HTML React generates in the browser.
In this article, we explain hydration mismatch errors in simple terms and show you, step by step, how to fix them in React and Next.js applications.

1. What Is Hydration in React and Next.js?

When using SSR (Server-Side Rendering), React sends pre-rendered HTML from the server.

Then the browser runs JavaScript to attach event listeners and activate the UI — this process is called hydration.

Hydration mismatch happens when:

This leads to warnings or even UI breaking in Next.js.

2. Common Causes of Hydration Mismatch

Hydration mismatch usually happens because the server and client render different UI.

Most common reasons:

Understanding the cause is the first step to fixing the issue.

3. Fix 1: Prevent Browser-Only Code from Running on the Server

React and Next.js SSR runs on the server where window and document do not exist.

❌ Wrong

const width = window.innerWidth;

✔ Fix using useEffect

const [width, setWidth] = useState(0);

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

Why It Works

4. Fix 2: Avoid Time-Based or Random Values During Render

❌ Wrong

<p>{new Date().toISOString()}</p>

❌ Wrong

<p>{Math.random()}</p>

These values differ between server and client.

✔ Fix

const [time, setTime] = useState(null);

useEffect(() => {
  setTime(new Date().toISOString());
}, []);

5. Fix 3: Wrap Client-Only Components in "use client" (Next.js 13+)

If you are using Next.js 13 with the App Router:

Example

"use client";

export default function ClientOnlyComponent() {
  return <div>Client side only</div>;
}

Why?

6. Fix 4: Use Dynamic Import with SSR Disabled

If a component depends on browser APIs or behaves differently on the client, disable SSR.

Example

import dynamic from "next/dynamic";

const MapComponent = dynamic(() => import("../components/MapComponent"), {
  ssr: false,
});

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

Why It Works

7. Fix 5: Ensure Initial State Matches on Server and Client

❌ Wrong (Server: 0, Client: 10)

const [count] = useState(window.innerWidth);

✔ Fix

const [count, setCount] = useState(0);

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

Initial state must match in SSR.

8. Fix 6: Avoid Conditional Rendering That Changes Between Server and Client

❌ Wrong

{typeof window !== "undefined" && <Sidebar />}

This causes SSR to render nothing, and client to render <Sidebar /> — mismatch.

✔ Fix using dynamic import

const Sidebar = dynamic(() => import("./Sidebar"), { ssr: false });

9. Fix 7: Use useEffect Instead of useLayoutEffect on the Server

React warns when using useLayoutEffect during SSR.

✔ Fix

useEffect(() => {
  // safe for client
}, []);

If you must use it, wrap it:

const useIsomorphicLayoutEffect =
  typeof window !== "undefined" ? useLayoutEffect : useEffect;

10. Fix 8: Ensure Data Fetching Uses the Same Source

Next.js App Router allows server components and client components.

If the server fetches data differently from the client, HTML will differ.

Fix

11. Fix 9: Use Suspense and Streaming Properly (Next.js 13+)

Streaming can cause UI mismatches if not coordinated.

Tips

12. Debugging Hydration Errors (Important)

1. Check Browser Console

It shows exact element mismatch.

2. Add temporary logs

console.log("Server HTML:", htmlString);
console.log("Client Render", element);

3. Disable JavaScript temporarily

If server UI looks different → mismatch exists.

4. Use React DevTools Hydration Debug Mode (React 18+)

Helps locate mismatched components.

13. Best Practices to Avoid Hydration Mismatches

Conclusion

Hydration mismatch errors in React and Next.js happen when the HTML rendered on the server does not match what React renders in the browser. By avoiding browser-only code during SSR, ensuring consistent state, handling time-based and random values correctly, and using Next.js features like dynamic imports and client components, you can completely eliminate hydration issues. With these best practices, your React and Next.js apps will become more stable, error-free, and production-ready.