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
Hydration SafetyView source ↗

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 renderBad
app.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.
  • defaultValue ignores later prop changes; reset with key.