HP1001 (text-mismatch) means the server and browser rendered different text.
The finding shows both values, the element and, when available, its source
line. Check whether the component reads the clock, locale or browser storage
during render. Give both sides the same initial value.
| Code | HP1001 |
|---|---|
| Name | text-mismatch |
| Default severity | Error |
| Group | DOM mismatches |
| What it means | The server HTML contains different text than the browser rendered during hydration. |
What HP1001 (text-mismatch) means
React expects the first browser render to match the server's text. If it does not, React discards that part of the server HTML and renders it again. The user may see a flash or lose input entered before hydration finished.
hydration-proof checks both sides of the difference:
- It sees text React replaced during hydration.
- It also compares text in elements React kept, so a difference is not missed just because React left the server node in place.
If React re-rendered the surrounding branch, the evidence says which branch it discarded. You do not get a second HP1010 finding for the same problem. A whitespace-only difference is HP1015 instead.
The React error it matches
In development, React usually reports a text mismatch too. hydration-proof keeps React's message with the finding. The wording depends on the React version and build:
Hydration failed because the server rendered text didn't match the client.
Text content does not match server-rendered HTML.
Warning: Text content did not match. Server: "5:00 AM" Client: "10:00 AM"
Minified React error #418; visit https://react.dev/errors/418Text content does not match server-rendered HTML covers the React 18 wording, and the server rendered HTML didn't match the client the React 19 one.
Likely causes
Start with the two values in your report. They often point to one of these causes:
| Cause | What differs |
|---|---|
| Time-dependent value | Date.now() or new Date() read during render |
| Timezone difference | A date formatted in the server's and the browser's timezone |
| Locale-dependent formatting | toLocaleString() with the runtime's default locale |
| Random value | Math.random() or crypto.randomUUID() in render |
| Browser storage | localStorage read behind a typeof window check |
| Media query | matchMedia or the window size read during render |
| Browser-only API | navigator.userAgent and other browser globals |
| Different data | The client fetched the data again and got a new result |
How to fix it
The first browser render must use the same text as the server. Pass a value
from the server as a prop, or show a stable placeholder and update it in
useEffect after hydration.
For example, a greeting that reads localStorage renders "guest" on the server
and the stored name in the browser:
"use client";
export function Welcome() {
const name =
typeof window === "undefined"
? "guest"
: (localStorage.getItem("name") ?? "guest");
return <p>Welcome back, {name}</p>;
}Render the value both sides agree on first, and read storage after hydration:
"use client";
import { useEffect, useState } from "react";
export function Welcome() {
const [name, setName] = useState("guest");
useEffect(() => {
setName(localStorage.getItem("name") ?? "guest");
}, []);
return <p>Welcome back, {name}</p>;
}If the value comes from a date, pass the server's time and an explicit locale
and timeZone. If it comes from fetched data, send the data the server used
to the client. When the cause is unclear, run hydration-proof test --probe:
it reloads the page with one factor changed at a time. See
probes for the factors it can test.
Prevent it with ESLint
The ESLint plugin reports the usual sources in render code:
no-date-in-render,
no-random-in-render,
no-locale-without-explicit-locale,
no-timezone-without-explicit-timezone,
no-storage-in-initial-render and
no-window-render-branch.
When the difference is intentional
For a value that is meant to differ, such as a live clock, put
suppressHydrationWarning on the element that holds it: React keeps the server
text, and hydration-proof lists the difference as
HP6001 (info) instead. ignore.textPatterns ignores a
text difference when both values are equal after removing the patterns, for
example /\d{2}:\d{2}/ for times. See ignoring findings.
Example
✖ /status 842ms 1 error
HP1001 Text differs between server and client · app/status/rendered-at.tsx:4
server "Rendered at 1767225600000" → client "Rendered at 1767225600412"
Possible cause: Time-dependent value. Fix: Pass the server timestamp as a prop or render the time after mount.The cause is a suggestion unless a probe confirms it. Open the HTML report for the source code, React's message and a screenshot of the element.