🐛

ColorZilla が引き起こす React Hydration Failed

2025/02/12に公開

解決方法

  • ColorZilla 拡張機能の無効化
  • <body> タグに suppressHydrationWarning 属性を付与する

背景

Hydration Failed は、React 開発者なら一度は遭遇するエラーです。この記事では、拡張機能 ColorZilla が Hydration Failed を引き起こす原因と、その解決方法について解説します。

前提知識

Hydration

React における Hydration とは、サーバーで生成された静的な HTML に対して、クライアント側で JavaScript の機能を結びつけ、インタラクティブなアプリケーションへと変換する処理のことです。

In React, “hydration” is how React “attaches” to existing HTML that was already rendered by React in a server environment. During hydration, React will attempt to attach event listeners to the existing markup and take over rendering the app on the client.

引用元: Hydrating server-rendered HTML

Hydration の概念が分かりにくい場合は、こちらの記事も参考にしてください。

Hydration Failed

Hydration Error とは、サーバー側で生成された静的な HTML と、クライアント側で React が再レンダリングして生成した HTML とで不一致が生じた場合に発生するエラーです。

ColorZilla が原因で Hydration Error が発生

通常通り create-next-app でプロジェクトをセットアップし、npm run dev で開発サーバーを起動すると、以下のような Hydration Failed が発生しました。

エラーメッセージを確認すると、ColorZilla が <body> タグに付与する cz-shortcut-listen という属性が原因であることがわかります。なお、私の環境では DeepL という拡張機能も <body> 内にスクリプトタグを追加していますが、DeepL のスクリプトは <body> 内に挿入されるため、Hydration Failed の対象外となり問題になりませんでした。一方、ColorZilla は <body> タグそのものに属性を追加するため、サーバーで生成された HTML とクライアント側で再現された HTML に不一致が生じ、Hydration Failed を引き起こします。

React 19 の公式説明によると、サードパーティのスクリプトやブラウザ拡張によって追加された要素が原因の不一致について、以下のような改善が行われています。

We’ve improved hydration to account for third-party scripts and browser extensions.
When hydrating, if an element that renders on the client doesn’t match the element found in the HTML from the server, React will force a client re-render to fix up the content. Previously, if an element was inserted by third-party scripts or browser extensions, it would trigger a mismatch error and client render.
In React 19, unexpected tags in the <head> and <body> will be skipped over, avoiding the mismatch errors. If React needs to re-render the entire document due to an unrelated hydration mismatch, it will leave in place stylesheets inserted by third-party scripts and browser extensions.
引用元: React 19 Blog

つまり、<head><body> 内にサードパーティによって挿入されたタグは、差分検知時にスキップされる仕組みになっています。しかし、ColorZilla は <body> タグ自体に属性を追加するため、差分検知の対象となり Hydration Failed を引き起こしてしまうのです。

ColorZilla による Hydration Failed を回避する方法としては、拡張機能自体を無効化するか、または <body> タグに suppressHydrationWarning 属性を付与する方法があります。

Discussion