Hydration Proof

Search documentation

Find a page or section

HP4002: A browser extension changed the page

HP4002 (extension-mutation) means a browser extension such as a grammar checker or password manager changed the page before hydration. When to ignore it.

HP4002 (extension-mutation) means the page changed before hydration in a way typical of browser extensions: grammar checkers, password managers, dark mode tools. It is an info finding, because there is nothing to fix in your code. Ignore it when it is expected, for example when your scenario simulates an extension.

CodeHP4002
Nameextension-mutation
Default severityInfo
GroupChanges made outside React
What it meansChanges typical of browser extensions (grammar checkers, password managers, translators) were found.

What the HP4002 extension mutation finding means

It comes from the same comparison as HP4001: the DOM the browser parsed from the server HTML against the DOM right before React hydrated. A change counts as an extension's when it:

  • adds an attribute extensions are known for: data-new-gr-c-s-check-loaded, data-gr-ext-installed and data-gramm (Grammarly), data-lt-installed (LanguageTool), password manager and Dark Reader attributes, data-ms-editor, cz-shortcut-listen or bis_*;
  • or inserts a custom element (a tag with a dash, such as <grammarly-desktop-integration>) directly into <html> or <body>.

Other changes an extension makes, such as a translator rewriting text, look like any other script and are reported as HP4001.

Playwright starts the test browser with a clean profile, so HP4002 usually means a scenario simulates an extension with initScripts, or the run uses a browser profile that has extensions installed.

The React warning your users see

Real users do have these extensions. In a React 18 development build, the attributes a grammar checker adds to <body> produce this warning:

Warning: Extra attributes from the server: data-new-gr-c-s-check-loaded,data-gr-ext-installed

Extra attributes from the server explains it. React 19 reports the same situation as attributes that didn't match.

Likely causes

  • A browser extension in the test browser's profile.
  • A scenario that simulates one on purpose, to check that the page survives it.

How to fix it

This comes from a browser extension on the test machine or simulated by your scenario; ignore it if it is expected.

  1. If you did not expect it, test with a clean browser profile: the default Playwright browser has no extensions.
  2. If you simulate an extension on purpose, ignore its attributes, so they are never compared, or ignore the code with a reason (below).
  3. If the warning in your own console bothers you, suppressHydrationWarning on <body> stops React from reporting that element's own attributes. It does not cover anything inside <body>.
hydration-proof.config.ts
import { defineConfig } from "hydration-proof";
 
export default defineConfig({
  ignore: {
    attributes: [/^data-gr-/, "data-new-gr-c-s-check-loaded"],
    issues: [
      { code: "HP4002", reason: "The extensions scenario simulates Grammarly" },
    ],
  },
});

Info findings do not fail the run and are not printed in the terminal list; the HTML and JSON reports show them. See ignoring findings for every way to silence one.