Matthew C.
—You have a Next.js application where the pre-rendered HTML from the server in your Next.js component does not match the HTML of the component in the client browser. If the HTML after this first render in the browser does not match the pre-rendered HTML, you’ll get an error message:
Warning: Text content did not match. Server: ..." Client: ...
A common cause for this warning is using browser APIs in your rendering logic:
"use client"; export default function ClientComponent() { return ( <div> {typeof window !== "undefined" ? "window defined" : "window undefined"} </div> ); }
During the first render in the browser, React hydrates the component. This is a process where React makes the component interactive by attaching event listeners to elements. Other common causes for this hydration warning include:
To fix the issue you can use the useEffect
hook to render different content on the client, disable server-side rendering, or suppress the hydration warning if appropriate.
useEffect
Use the useEffect
hook to render different HTML on the client and ensure that the HTML after the first render on the client matches the pre-rendered HTML sent from the server. The effects run after hydration.
We can use useEffect
to fix the hydration warning in the code example above:
"use client"; import { useState, useEffect } from "react"; export default function ClientComponent() { const [isClient, setIsClient] = useState(false); useEffect(() => { setIsClient(true); }, []); return <div>{isClient ? "window defined" : "window undefined"}</div>; }
The isClient
state variable ensures that the text “window defined” is only rendered after the component is mounted, after the first render on the client (hydration).
If you are using a client-only library, or you only want to load a client component after a specific action happens on the client, such as a user clicking a button, then you can lazy load your client component and disable pre-rendering on the server. This will mean that your client component is only rendered on the client. Note that this may increase the time taken for the page to initially load.
The warning may be due to content that will differ between the client and server, such as rendering a timestamp, as in the example code below:
const currentTime = new Date().toLocaleTimeString(); return <div>The current time is: {currentTime}</div>;
In this case, you can suppress the hydration warning by adding the suppressHydrationWarning
attribute to the element:
const currentTime = new Date().toLocaleTimeString(); return <div suppressHydrationWarning>The current time is: {currentTime}</div>;
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,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.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.