HTML mismatch
Context: what hydration is
After SSR, the browser receives ready-made HTML. The client-side JavaScript (React, Vue, etc.) then performs the same render to "attach" logic and events to the already existing DOM. This process is called hydration.
For hydration to succeed:
The client-side virtual DOM must exactly match the HTML the server generated.
What happens on a mismatch
1. React tries to "reconcile" the DOM
React compares the existing HTML (from the server) with what it expects during client-side rendering.
If the differences are minor (for example, a class attribute or the text inside an element), React may try to silently fix the DOM.
If the differences are significant, React will log a warning or even re-render part of the tree.
2. React logs an error to the console
You will see a message like:
Warning: Text content did not match. Server: "42" Client: "43"or
Warning: Hydration failed because the initial UI does not match what was rendered on the server.This means React expected one tree and got a different one.
3. Possible consequences
| Situation | What happens |
|---|---|
| Small differences (text, attribute) | React silently fixes the DOM, but this can trigger a "reflow" or a flickering interface |
| Significant differences (different structure) | React removes the old HTML and re-renders the component from scratch |
| Widespread mismatches | Lost state, effects running twice, logic bugs |
| In strict mode (React 18 StrictMode) | React logs a warning and may reset the whole tree |
Example
The server returned:
<div id="root">
<p>Today: October 17</p>
</div>The client rendered:
<div id="root">
<p>Today: October 18</p>
</div>React detects the mismatch and shows:
Warning: Text content did not match. Server: "Today: October 17" Client: "Today: October 18"The user sees a brief content "flicker" - React replaces the text after hydration.
Main causes of hydration errors
1. Using "unstable" values
Math.random()Date.now()new Date()- UUID / random keys
- random ids (for example,
id={Math.random()})
Solution: Generate them on the server ahead of time and pass them through props.
2. Code that depends on the browser
The server has no window, document, navigator, localStorage, and so on.
Wrong:
const width = window.innerWidth; // Error during SSRCorrect:
const [width, setWidth] = useState(0);
useEffect(() => setWidth(window.innerWidth), []);3. Conditional rendering that depends on the environment
If a component renders differently depending on:
- screen size,
- the user's session,
- locale,
- cookie / theme mode.
Example:
{typeof window !== "undefined" && <Sidebar />}The server has no window → Sidebar does not render.
The client has window → Sidebar appears → mismatch.
Solution:
Render with the same conditions, or use useEffect for client-only code.
4. A difference in data between the server and the client
If SSR loads one set of data and the client requests different data again → an HTML mismatch.
Solution:
- Pass
initialDatafrom SSR to the client through__INITIAL_STATE__orpageProps. - Use the same data-loading logic.
How React reacts (React 18+)
| Version | Behavior |
|---|---|
| React 17 and below | Silently fixed the differences (often caused bugs) |
| React 18 | Explicitly warns in the console and may reset the DOM |
| React 18 (StrictMode) | Checks with a double render to catch mismatches |
How to avoid mismatches
- Use deterministic data during SSR.
- Do not render browser-dependent elements before hydration.
- Pass all initial props/data to the client.
- Test the SSR render with
ReactDOMServer.renderToString()locally. - Enable
StrictMode- it helps catch hydration bugs.
Conclusion
If the HTML generated on the server does not match the client's:
- React logs a warning or a hydration error.
- A re-render may occur, along with lost state or a flickering interface.
- This is often caused by non-deterministic rendering (dates, randomness, window, and so on).
Ideal SSR hydration means the same HTML, regardless of whether it was generated on the server or the client.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.