初期UIがサーバーでレンダリングされたものと一致しないため、ハイドレーションに失敗したら、とても陰鬱な気持ちになると思います。
Next.jsやReactベースのメタフレームワークを使ってサーバーレンダリングされたページを構築しているなら、ハイドレーションエラーが起きると最悪な気持ちになり、デバッグが困難であることはご存じでしょう。
Reactにおけるハイドレーションとは、サーバー上でHTMLとしてレンダリングされたReactアプリケーションが、ブラウザ上でインタラクティブになるときに発生するプロセスのことです。
ハイドレーションエラーは、クライアント上でReactによってレンダリングされたマークアップが、最初にサーバーからレンダリングされたHTMLと一致しない場合や、サーバーから無効なHTMLが送信され、Reactがそれを修正できなかった場合に発生します。
日付やローカライズなどであれば、避けられないケースとなることも有り得ます。Reactのコードでは、このような不可避な差異に対するエラーを抑制することができますが、ほとんどのハイドレーションエラーは、アプリに何らかのバグがあることを示しています。
この記事では、ハイドレーションエラーの修正方法ではなく、Sentryを使用したハイドレーションエラーをデバッグする方法について説明します。
開発中にハイドレーションエラーが発生すると、選択したJavaScriptフレームワークは通常、エラーを引き起こしたコードに関するいくつかの詳細とともに、大きなエラーメッセージを表示します。
しかし、ハイドレーションエラーは通常、本番環境では表示されませんし、原因も曖昧な状態になりがちです。
一般的なユーザーは、おそらくエラーレポートとともに有用なスクリーンショットを提供することはできないでしょう。
また、ブラウザの開発者ツールなどでエラーを探そうと思うことは皆無に近いでしょう。
さらに言えば、Sentryが自動的に作成するエラー問題も、解決にはあまり役に立たないでしょう。
『セッションリプレイ』を使って原因追及!
もしあなたがSentryのセッションリプレイ機能を用いることで、ユーザーがハイドレーションエラーを起こしたときにユーザーセッションの再現を取得する設定なら、Sentryは特定のハイドレーションエラーのイシューを自動的に作成します(しかも無料です!)
- Sentryが自動的に特定のハイドレーションエラー問題を作成します。
- すべての同じエラーをグループ化します。
- エラー発生時に存在したサーバーレンダリングと、クライアントレンダリングの両方のマークアップをキャプチャします。
- ビジュアルモードと、プレーンHTMLモードの両方で差分を表示します。
注意点として、SentryのJavaScript SDK、バージョン7.87.0以上を使用していることと、セッションリプレイを有効にしていることを確認してください。
グループ化されたハイドレーションエラーが、Sentryでどのように見えるかご紹介します。
- Hydration Error(ハイドレーションエラー)という名前なので、課題リストビューで簡単に見つけることができます。
- 表示するイベント(推奨、最新、最古)を選択し、イベント間を移動してコンテキスト情報を比較できます。
- サーバーとクライアントの間でスライドする差分を表示します(差分ビューアを開くと、ビジュアル差分とHTML差分を並べて表示することもできます)。
- 『ハイドレーションエラーの解決』をクリックすると、ハイドレーションエラーの解決に関するヘルプが表示されます。
ハイドレーションエラーのデバッグ
標準的なハイドレーションエラーの内容は、サーバーでレンダリングされたHTMLがクライアントでレンダリングされたHTMLと一致しなかったと述べていることが多いです。
そのため、差分ビューアーはこれらの違いを見つけるのにとても役立ちます。
Before「ビューはサーバーでレンダリングされたもの」で、
After「ビューはReactがクライアントでレンダリングしたもの」です。
もしかすると、こちらの例でお気づきかもしれません。
それは「変更前」と「変更後」が見た目がほとんど同じに見えるということです。
HTMLの差分を調べると、サーバーでは空白のページがレンダリングされ、クライアントではHTMLがレンダリングされている、というケースがあります。
しかしこれは正しくない状態です。ブラウザのネットワークタブで確認したところ、HTMLは間違いなくサーバーでレンダリングされています。
ハイドレーションエラーの原因となっているコードの本当の問題は、サーバー側でレンダリングされたHTMLと、クライアント・レンダリングされたHTMLが一致していないことではなく、自身が作成したHTMLが無効で(<p>が<p>の中に含まれている)、Reactがエラーを投げたことです。これが『ハイドレーションエラーが最悪な理由』です。
ではなぜdiff(ファイル差分)によると、サーバー上にHTMLがレンダリングされていないように見えるのでしょうか?
Reactが無効なHTMLのために無意味なハイドレーションエラーを投げたことを考えると、Sentryは問題が何であるかについて最善の努力を尽くして推測するしかありません。
通常、あるイベントに意味のないdiffがある場合、別のイベントの方が役に立つかもしれません。
要するに、Reactがハイドレーションエラーを投げたときは、修正が必要な問題があるということです。
そして、Reactは本番環境で問題を修正するために必要な詳細を教えてくれないので、Sentryはハイドレーションエラーの差分ツールの空白を可能な限り埋めることで、問題をよりよくデバッグできるようにしてくれます。
ハイドレーションエラーの問題や差分を作成すると、Sentryの利用金額は増える…?
すでにセッションリプレイを使用している場合、自動的にグループ化されたハイドレーションエラー課題を『無料』でご利用いただけます。
Sentryのハイドレーションエラー問題は、リプレイとその関連データから生成されるため、エラークォーターにも影響しません。さらに、ハイドレーションエラーのアラートもデフォルトで表示されます。
セッションリプレイを使っているなら、Sentry に送信される前に、デフォルトですべてのテキストコンテンツを「 * 」でマスクし、クライアント上のすべてのメディア要素をブロックすることに気づいたかもしれません。
この記事では、Session Replay SDK がどのように設定されているかによって、ハイドレーションエラーの画像に示されている例は、「 * 」ではなくテキストを表示しています。
もしあなたが個人を特定できる情報(PII)のないコンテンツベースのWebサイト制作に取り組んでいるなら、セッションリプレイの初期化でmaskAllTextとblockAllMedia設定オプションを設定することで、デフォルトのテキストマスキングと画像ブロックを無効にすることができます。
その例を以下に示します。
これは、この記事で示されたような偽のハイドレーションエラー(実際には無効なHTMLエラー)をデバッグする際に非常に役立ちます。
※あなたのサイトに機密データがない場合、または実際の機密データをマスキングまたはブロックするための他のオプションをすでに設定している場合にのみ使用してください。詳細は、Session Replayのプライバシー設定については、Sentryのドキュメントを参照してください。
デバッグしやすくする鍵
これまで、本番でのハイドレーションエラーは、謎に包まれた存在でした。
Sentry Replay SDKを使用すれば、HTMLの差分とハイドレーションエラーの可能な限りのコンテキストを得ることができます。
そして、デバッグや修正を迅速に行うことが可能になります。
これは最終的に開発者としてのあなたを助けるだけでなく、利害関係者(ステークホルダー)、顧客、そして最も重要なユーザーなど、他のすべての人にも利益をもたらします。
Sentryは無料でお試しいただけます。
さあ、手軽で快適なバグ修正を体感してください。
IchizokuはSentryと提携し、日本でSentry製品の導入支援、テクニカルサポート、ベストプラクティスの共有を行なっています。Ichizokuが提供するSentryの日本語サイトについてはこちらをご覧ください。またご導入についての相談はこちらのフォームからお気軽にお問い合わせください。