Register now: How design teams use AI to prototype

What are best AI tools? Take the State of AI survey

Builder.io
Builder.io
Contact sales
‹ Back to blog

Web Development

Announcing React Hydration Overlay - Easily Squash Hydration Errors

December 13, 2023

Written By Sami Jaber

TL;DR: go to https://github.com/BuilderIO/hydration-overlay to install the overlay and debug your hydration mismatch.

Last week, I spent hours debugging a tricky hydration mismatch. I had to:

  • copy the HTML sent over the wire,
  • console.log the HTML generated on the client and copy it,
  • paste both of them into an online diff checker tool.

I got tired of doing this, so I automated it. Hence @builder.io/react-hydration-overlay!

How does it work?

The solution I landed on is fairly rudimentary (like all the best solutions!). The package works in 2 parts:

  • First, you use a plugin to inject hydration-overlay-initializer.js into your app's entry point. This script reads the HTML from the server and stores it, and then listens for hydration errors and stores the page's HTML that exists then.
  • Second, you wrap your app's root in HydrationOverlay, a component that will read the data from the previous step and display it in an overlay.

Currently, only Next.js via a Webpack Plugin. But PRs are more than welcome: what you need is to inject a script into the bundle's entry point, which is fairly straightforward task.

Install the dependnecy with npm (or pnpm, yarn, etc):

npm install @builder.io/react-hydration-overlay

Add the overlay component to the root of your app:

import { HydrationOverlay } from "@builder.io/react-hydration-overlay";

const App = () => {
  return (
    <HydrationOverlay>
      <YourApp />
    </HydrationOverlay>
  );
};

Add the plugin to your next.config.js

const {
  withHydrationOverlay,
} = require("@builder.io/react-hydration-overlay/next");

/** @type {import('next').NextConfig} */
const nextConfig = {
  /** your config here */
};

module.exports = withHydrationOverlay({
  /**
   * Optional: `appRootSelector` is the selector for the root element of your app. By default, it is `#__next` which works
   * for Next.js apps with pages directory. If you are using the app directory, you should change this to `main`.
   */
  appRootSelector: "main",
})(nextConfig);

And that's all. Read more in the project readme

As anyone who's had a React hydration mismatch knows, the errors are rather cryptic. In a large page, it becomes extremely difficult to find the mismatched element. While this tool isn't perfect, it automates away a cumbersome manual process that many currently resort to to pin down the exact mismatch.

NOTE: There is a WIP PR to fix this in React, so hopefully there will be a native solution to this problem soon. This plugin will remian handy for all older React versions.

When hydration fails, React will re-render your app on the client-side. It turns out that React renders things slightly differently in SSR VS CSR. The most visible one I've seen is style HTML attributes: whitespace and semi-colons are added in the CSR, and in some cases, the attributes are re-ordered and shorthand attributes are expanded (the most extreme case is all: unset which can seemingly turn into hundreds of properties!). So keep in mind that there will be some false positives when using this plugin. I still firmly believe that it is a net positive to have this tool in your arsenal when debugging hairy issues!

That's it! Go fix your hydration bugs!

Share

Twitter
LinkedIn
Facebook

Generate high quality code that uses your components & design tokens.

Try it nowGet a demo

Continue Reading
AI11 MIN
The best agentic IDEs heading into 2026
WRITTEN BYAlice Moore
October 29, 2025
webgl5 MIN
A brief intro to WebGL shaders
WRITTEN BYSteve Sewell
October 16, 2025
AI7 MIN
Create Apple-style scroll animations with CSS view-timeline
WRITTEN BYSteve Sewell
October 14, 2025