How do I fix the “Hydration failed because the initial UI does not match what was rendered on the server” error with Next.js and React 18?
This issue occurs because there is a mismatch between the React tree rendered during the first render in the browser (called hydration), and the React tree that was pre-rendered from the server.
Hydration is the process of React converting pre-rendered HTML into an interactive application by attaching event handlers. Hydration issues can be caused by several things:
typeof window !== 'undefined
or calls to localStorage
.<button>
nested in a <button>
tag).<div>
tag inside a <p>
tag.There are a few solutions you can utilize to solve this error.
Your browser console window can give you more descriptive errors, pointing you to the issue causing the hydration failure. For example:
Warning: Expected server HTML to contain a matching <h1> in <p>. h1 p main div
You might have a component that includes a <div>
tag that is nested inside a <p>
tag in another component.
Next.js allows you to disable SSR on particular components.
You can define a component with SSR disabled as follows:
const MyComponent = dynamic(() => import('../components/MyComponent'), { ssr: false })
If a component is not pre-rendered on the server, it will not cause a hydration mismatch error.
While you should ensure that a component renders the same content on the server and on the client to prevent hydration errors, you can render different client-side content during hydration by using useEffect
.
Below, useEffect
is used to toggle different content that is never pre-rendered by the server. This is because useEffect
is called during hydration. This also means that you can use browser APIs like localStorage
and window
in the client-side-only content.
import { useState, useEffect } from 'react'; export default function App() { const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); return ( <div> <h1> {isClient ? 'Never rendered on the server' : 'Prerendered on the server'} </h1> </div> ); }
suppressHydrationWarning
There are times when content will be different on the client and the server. In these situations, you can use the suppressHydrationWarning
HTML attribute to silence the hydration mismatch caused by a component.
Get actionable, code-level insights to resolve Next.js performance bottlenecks and errors.
Run the line of code below to:
Create a free Sentry account
Run the CLI install command to automatically add the Sentry SDK to your project:
npx @sentry/wizard@latest -i nextjs
Start capturing errors and performance issues
Loved by over 4 million developers and more than 90,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.