Skip to content

BuilderIO/hydration-overlay

Repository files navigation

Hydration Overlay 🕵️

This package displays an overlay during Hydration Errors, providing an explicit diff between the server-side and client-side renders.

after

Installation

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

Usage

HydrationOverlay

First, wrap the root of your app in the HydrationOverlay component.

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

export default function App() {
  return (
    <HydrationOverlay>
      <YourApp />
    </HydrationOverlay>
  );
}

Or, in the Next.js App Router, wrap {children} in your root layout:

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

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <HydrationOverlay>{children}</HydrationOverlay>
      </body>
    </html>
  );
}

Plugin

Second, add the plugin for your framework. Currently, we support Next.js & webpack.

Next.js

in 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);

webpack

Here is an example (still with Next), but using the webpack helper directly:

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

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  webpack: (config, options) => {
    config = withHydrationOverlayWebpack({
      appRootSelector: "#__next",
      isMainAppEntryPoint: (entryPointName) =>
        !options.isServer &&
        (entryPointName === "pages/_app" || entryPointName === "main-app"),
    })(config);
    return config;
  },
};

module.exports = nextConfig;

Notes

  • This package is currently in beta. Please report any issues you find!
  • This package is not intended for production use. We highly recommend you remove this package from your production builds.

Caveats

This package works by comparing the HTML received from the server with the HTML rendered by the client, which has one important consequence. React re-renders the entire app when hydration fails, potentially introducing even more changes.

The biggest example is style attributes: React appends ; to each one and alters the whitespace. In more extreme examples, it causes enormous diffs for properties like all: unset.

Therefore, this tool will give you false positives for style changes.

How It Works

  • The plugin injects 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 resulting HTML then.
  • The HydrationOverlay component reads both HTML strings and compares them, and renders the overlay.

Support

To add support for other frameworks, what is needed is a plugin that injects the hydration-overlay-initializer.js script into the app's entry point. See next.ts plugin for more information. PRs welcome!

  • Next.js
  • Remix
  • Vite SSR

Release process

Add changesets

in the same PR where your change is made, run:

pnpm c:add

and follow instructions to add changesets. You can then merge your PR.

Merge automated PR

Once your PR is merged, the changeset bot will open a PR with the changeset. You can merge this PR once CI passes. This will trigger a release.



Made with love by Builder.io