Minified React error #418 is a hydration mismatch in a production build: the HTML the server sent differs from the first render in the browser, so React threw it away and rendered the page again. Production hides which element. Reproduce it in development, or test the production build with a tool that compares the DOM, to find it.
The error
React 19:
Minified React error #418; visit https://react.dev/errors/418?args[]=HTML&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.React 18:
Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.In React 18 it is usually followed by #423, which says React rendered the whole page again.
What minified React error #418 means
React error 418 is the hydration mismatch error. Its full text depends on the React version:
| Version | Full message behind #418 | Covers |
|---|---|---|
| React 18 | Hydration failed because the initial UI does not match what was rendered on the server. | Elements. Text has its own code, #425 |
| React 19 | Hydration failed because the server rendered HTML didn't match the client. | Elements and text. Newer releases pass text or HTML as the argument |
The react.dev error 418 page decodes the number with the current React wording, even if your app runs React 18. Neither version puts the element or the values in the production message: the diff and the warnings that name the element exist only in development builds.
Attribute differences never produce #418. React 19 does not check attributes
in production at all, so a wrong class or href stays silent there.
Why it can appear only in production
The production server often renders in different conditions than your machine: another timezone (servers usually run in UTC), another locale, cached or statically built HTML, a CDN that minifies HTML, and real users' browser extensions. Each can create a mismatch you never see locally. See hydration errors only in production.
How to fix error 418
-
Get the full message. Load the same page with a development build and read the error and its diff. If development does not reproduce it, test the production build directly (see below).
-
Find the value that differs from the diff, or from the finding hydration-proof reports.
-
Fix its cause. Most production-only cases are dates, numbers and locales. Before, the number uses the server's locale on the server and the user's in the browser:
components/price.tsx export function Price({ amount }: { amount: number }) { return <span>{amount.toLocaleString()}</span>; }After, both sides use the locale the server chose, for example from the URL or a cookie:
components/price.tsx export function Price({ amount, locale, }: { amount: number; locale: string; }) { return <span>{amount.toLocaleString(locale)}</span>; }The common causes of hydration errors each have a fix guide.
-
Deploy and watch the error rate. One mismatch can hide the next, because React reports the first one per boundary.
Find every instance
hydration-proof tests the production build by default, and compares the DOM itself, so it names the element React's minified error leaves out:
npx hydration-proof test --mode both--mode both also runs the development server and marks findings that
appear in only one mode. The difference is reported with its own code, such
as HP1001 (text) or HP1007 (an
element), and what React did as HP1010 or
HP1011. When React reports #418 but the DOM
comparison cannot place it, you get HP2001. With
browser source maps (productionBrowserSourceMaps: true in Next.js), the
production finding also names the component.