HP1015 (whitespace-mismatch) means the server HTML and React's client render
differ only in whitespace. Your components rarely cause this: it usually means
something rewrote the HTML on its way to the browser, such as a CDN's HTML
minification. Turn off HTML minification for server-rendered React pages.
| Code | HP1015 |
|---|---|
| Name | whitespace-mismatch |
| Default severity | Error |
| Group | DOM mismatches |
| What it means | Only whitespace differs, which usually means something rewrote the HTML between the server and the browser. |
What HP1015 (whitespace-mismatch) means
To React, a space is text like any other. If a minifier removes the space
between Hello and <strong>world</strong>, a text node React expects is
missing, and hydration fails exactly as it would for different words.
hydration-proof reports HP1015 instead of HP1001 when
the two values are equal once all whitespace is removed, and when a
whitespace-only text node exists on one side only. The likely cause is
HTML rewritten by a CDN or proxy, with a higher confidence
when the response headers show one (such as cf-ray, x-amz-cf-id, x-cache
or via).
The package's /cdn-whitespace test page shows the difference: loaded
directly it is clean, and loaded through a proxy that collapses whitespace
between tags, like a CDN's minifier, it fails.
The terminal collapses whitespace when it prints values, so the two sides can
look alike there; report.json and the HTML report have the exact values.
Likely causes
- HTML minification at a CDN or proxy, for example a CDN's "Auto Minify" option.
- A server-side HTML post-processor or edge function that reformats the response.
How to fix it
- Turn off HTML minification that removes whitespace (for example CDN "Auto Minify") for server-rendered React pages.
- Avoid relying on whitespace-only text nodes between elements.
The first is the fix. The second makes a page less fragile: a space between two elements is a text node of its own, which is exactly the kind of whitespace a minifier collapses.
export function FooterLinks() {
return (
<nav>
<a href="/docs">Docs</a> <a href="/blog">Blog</a>
</nav>
);
}Spacing from CSS leaves nothing for a minifier to remove:
export function FooterLinks() {
return (
<nav style={{ display: "flex", gap: "0.5rem" }}>
<a href="/docs">Docs</a>
<a href="/blog">Blog</a>
</nav>
);
}When the difference is intentional
It rarely is. If you cannot change the CDN yet, an ignore.issues rule with
code: "HP1015", a reason and an expiry date keeps the run green while you
do; see ignoring findings.
Example
✖ /about 1.1s 1 error
HP1015 Whitespace differs between server and client (html rewritten by a cdn or proxy, 88%)
#intro in Intro
server: (absent)
client: "\" \""
components/intro.tsx:5:7
→ Turn off HTML minification or rewriting (e.g. Cloudflare Auto Minify, email obfuscation) for server-rendered pages.Here the minifier removed the space React renders between two elements, so the
server side is (absent) and the client side is that space, quoted.