Avoid hydration mismatches
The first client render must match the server HTML.
Web Interface Guidelinesvercel-labs · command.md
Inputs with `value` need `onChange` (or use `defaultValue` for uncontrolled) Date/time rendering: guard against hydration mismatch (server vs client) `suppressHydrationWarning` only where truly needed
From web-design-guidelines (Web Interface Guidelines).
A value nobody can change
Type in both fields, then try clearing them.
value, no onChangeBad- Tried
- 0
- Landed
- 0
- State
Warning: You provided a `value` prop to a form field without an `onChange` handler.
<input value={name} />Owned by someoneGood
- Tried
- 0
- Landed
- 0
- State
<input defaultValue={name} /><input name="name" defaultValue={user.name} />
<input value={name} onChange={(e) => setName(e.target.value)} />
<input value={user.id} readOnly />
“Today is…” across a time zone
Press Load page, then move the server clock and reload.
new Date() in renderBadapp.example/inboxHydrated
Today is
{format(new Date())}GuardedGood
app.example/inboxHydrated
Today is
Where to suppress the warning
Tick where the prop belongs.
Tree3 warnings
class="dark" from a theme script
Matches
Parent
Thu, Sep 24 vs Wed, Sep 23
ResultNeeds work
- Theme
- Date on screen
<html lang="en" suppressHydrationWarning>
Why it matters, pros and cons
Why it matters
Clocks and time zones differ between server and client, so the HTML won't match.
Pros
- No flash from server date to visitor date.
- A quiet console, so real mismatches stand out.
- Every field types, or is honestly
readOnly.
Cons
- Render-after-mount paints an empty slot first.
- A zone cookie is missing on the first visit.
defaultValueignores later prop changes; reset withkey.