A hydration error hiding in an SVG title
React error 418 on every production page load, invisible to visitors. The cause was one line in a diagram.
While redesigning this site I ran every page through a headless browser, and production builds threw this on every load:
Error: Minified React error #418; visit https://react.dev/errors/418?args[]=HTML&args[]= for the full messageError 418 means the HTML the server rendered didn't match what React rendered on the client, so React threw that part away and rendered it again in the browser. Visitors saw nothing wrong, and development mode didn't flag it in my checks. It only showed up in production builds.
The wrong suspect
I'd just added a component that fades sections in as you scroll, and it changes the DOM after the page loads. It looked guilty. I removed it, rebuilt, and my check came back clean.
It wasn't fixed. My check only listened for console.error, and this error is thrown as an uncaught exception, which arrives as a page error. Once I listened for both, the error was back, and it was on the old version of the site too. It had been there all along.
If you're checking a page for errors with Playwright, listen to both:
page.on("console", (m) => m.type() === "error" && errors.push(m.text()));
page.on("pageerror", (e) => errors.push(String(e)));Bisecting builds
With no message to go on, I removed things one at a time and rebuilt each time: analytics, the animated terminal, the navigation, the structured data. The error stayed. A page with nothing but <p>hello</p> inside the same layout was clean, so it was somewhere in the homepage.
It turned out to be the cluster map, an SVG with a <title> on each node for screen readers:
<title>
{p.name}: {p.status}
</title>That looks like one string, but it's three children: the name, the text ": ", and the status. The diagram's own title had the same shape, with a number joined on using {" "}.
React's documentation for <title> warns about exactly this pattern, <title>Results page {pageNumber}</title>, and says the children must be a single string. That page is about the document title, though, and it says a <title> inside an <svg> gets no special treatment. So I can't point to the precise mechanism. What I can say is that the error appeared with the multi-part titles and disappeared when they became single strings, with nothing else changed:
<title>{`${p.name}: ${p.status}`}</title>I rebuilt with everything else put back, and the error stayed gone.
What I'd check first next time
- A hydration error that only appears in production is worth hunting even when nothing looks broken. React is quietly re-rendering part of the page on every visit.
- Check for page errors, not just console errors.
- Give every
<title>, in the document head or in an SVG, a single template string rather than text mixed with{}. It costs nothing and rules this out.