Probes prove the cause of a hydration mismatch instead of guessing it. With
--probe, hydration-proof reloads each page that has a value mismatch with the
browser clock and random values fixed, then once per factor with exactly one
thing changed. If the client value changes, or the finding disappears, when
only that factor changes, the factor is the cause.
Turn probes on
npx hydration-proof test --probeOr in the config, with probes: true, or with options:
import { defineConfig } from "hydration-proof";
export default defineConfig({
probes: { factors: ["time", "random"], maxPages: 5 },
});Probes are off by default because they cost extra page loads (see below).
How to prove the cause of a hydration mismatch
Every finding already has a likely cause: an informed guess, with a confidence, made from the values that differ, the code around the source line, the scenario and the stage where the difference started. A probe turns the guess into a test:
- The page is loaded with the browser clock and
Math.random()fixed. - It is loaded again, identically. This is the control.
- It is loaded once more for each factor, with only that factor changed.
- hydration-proof compares the finding across the loads.
| Factor | What changes | Proves |
|---|---|---|
time | The browser clock moves by 3 days, 7 hours, 11 minutes and 13 seconds | Time-dependent value |
random | A different seed for Math.random() and crypto.getRandomValues() | Random value |
locale | The browser locale becomes the server's (or another one) | Locale-dependent formatting |
timezone | The browser timezone becomes the server's (or another one) | Timezone difference |
theme | Light ↔ dark | Theme preference |
viewport | Desktop ↔ mobile | Screen size or media query |
storage | No localStorage, sessionStorage or storageState from the scenario (only when it has them) | Browser storage |
The clock moves by an odd amount so that every field of a date changes at once: the day, the hour, the minute and the second.
Proven or likely?
A finding whose client value changes, or that disappears, when only one factor
changes has that cause proven. The terminal shows proven where it
otherwise shows a percentage, and the run ends with a summary of what the
probes found:
HP1001 Text differs between server and client (timezone difference, proven)
#last-login in LastLogin
server: "Signed in at 5:00 AM"
client: "Signed in at 10:00 AM"
Probes
HP1001 /dashboard #last-login proven: timezone differenceThe finding's evidence says what changed, for example that the client rendered one value instead of another when only the browser timezone changed. Its list of fixes starts with the fixes for the proven cause.
When several factors change the finding, the most specific one names the cause, and the evidence lists the others. Factors that changed nothing are listed too, and a likely cause that a probe ruled out loses confidence.
What if an identical reload renders differently?
Then the value does not come from the browser. The clock and random values were fixed, so it comes from the server or an API that answers differently each time. The finding's cause becomes server and client used different data, and the other factors are marked inconclusive, since a page that changes on its own cannot prove anything else.
What do probes cost?
Only value mismatches are probed: text, attribute, style, class and
dangerouslySetInnerHTML differences, plus form state
(HP1001 to HP1006,
HP1012 and HP1013). Ignored,
suppressed and info findings are skipped.
- Each probed page costs up to 9 extra page loads: the fixed load, the control, and one per factor.
maxPages(default5) caps the pages probed per run. Pages with the most errors go first, and a note says how many were left out.- The run ends with a note of how many extra loads the probes took.
Narrow factors when you only suspect one or two causes.
Probes never hide a finding
The server is never changed. Fixing the browser clock only makes the loads
comparable with each other; the server keeps its real clock, so a
time-dependent value is still found. The same goes for a scenario's clock
and randomSeed options: they make client values repeatable between runs, and
hide nothing (see scenarios).
Options
| Option | Type | Default | Description |
|---|---|---|---|
| factors | ProbeFactor[] | all that apply | What to vary. |
| maxPages | number | 5 | Most pages probed per run. |
Related
- How hydration-proof works: stages, comparisons and causes
- All causes of hydration errors and their fixes
- Environment matrix: find the locale or browser a bug needs
- Fix date and time hydration errors
- HP1001: text differs between server and client