Hydration Proof

Search documentation

Find a page or section

HP1015: Whitespace differs between server and client

HP1015 (whitespace mismatch): only whitespace differs between the server HTML and React's render, which usually means a CDN or proxy minified the HTML.

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.

CodeHP1015
Namewhitespace-mismatch
Default severityError
GroupDOM mismatches
What it meansOnly 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.

footer-links.tsx
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:

footer-links.tsx
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.