Skip to main content
whitep4nth3r logo

Sentry can’t fix React hydration errors, but it can really help you debug them

Hydration failed because the initial ui does not match what was rendered on the server. Great.

Hydration failed because the initial ui does not match what was rendered on the server. Don’t you just ~~love~~ hate it when that happens?

If you’re building server-rendered pages with Next.js or any React-based meta-framework, you know hydration errors suck and are usually difficult to debug. Hydration in React is the process that happens when a React application that was rendered as HTML on the server is made interactive in the browser. Hydration errors happen when the markup rendered by React on the client doesn’t match the initial server-rendered HTML, or when invalid HTML was sent by the server, and React couldn’t fix it. Sometimes this is unavoidable, for example, with dates and localization. You can suppress errors for these unavoidable differences in your React code, but most hydration errors would indicate that you’ve got some bugs in your app.

This article is not about how to fix hydration errors but how to debug them using Sentry. When hydration errors happen in development, your JavaScript framework of choice will usually show you a large error message with some details about the code that triggered the error. However, hydration errors aren’t usually visible or obvious in production, and your average real-world users probably won’t be able to provide useful screenshots with error reports (and probably won’t think to look in the browser console for errors). What’s more, the automatic error issue created by Sentry won’t be very useful, either.

Error issue in Sentry created by a hydration issue. The error message is not useful and there isn’t much context associated with the issue.

But wait, Session Replay has a superpower

If you’re using Sentry’s Session Replay to get reproductions of user sessions when a user triggers a hydration error:

  1. Sentry will automatically create a specific Hydration Error Issue for you (for free!),

  2. group all the same errors together,

  3. capture both the server-rendered and client-rendered markup that existed when the error happened,

  4. and show you the diffs in both visual and raw HTML modes.

Just make sure you’re using Sentry’s JavaScript SDK, version 7.87.0 or above, and you’ve got Session Replay enabled to get the good stuff.

Here’s what a grouped Hydration Error looks like in Sentry:

  • It is named “Hydration Error,” so you can find it easily in the issue list view.

  • Choose which event to view (recommended, latest, oldest) and navigate between events to compare contextual information.

  • View a sliding diff between the server and the client (open the diff viewer to also view a side by side visual diff and HTML diff).

  • Click the “Resolving Hydration Errors” link to get more help on solving hydration errors.

Grouped hydration error issue view showing how to navigate between grouped events, highlighting the diff viewer, and pointing to a link to get more info about how to solve hydration errors.

Debugging hydration errors

Given that the standard hydration error message states that the server-rendered HTML did not match the client-rendered HTML, the diff viewer is really helpful in finding those differences. The “Before” view is the server-rendered version, and the “After” view is what React rendered on the client.

Hydration error side by side visual diff viewer, showing that the server rendered page is the same as the client rendered page.

What you might notice in this example, however, is that the “Before” and “After” versions look the same visually. When inspecting the HTML diff, we see a blank page rendered on the server and HTML rendered on the client. This isn’t correct. HTML is definitely being rendered on the server; I checked in my browser’s network tab.

Hydration error HTML diff viewer, showing a blank page on the server and invalid HTM on the client.

The real issue in the code causing the hydration error is not that the server-rendered and client-rendered HTML don’t match, it’s that my HTML is invalid (a <p> is contained within a <p>) and React threw an error. This is why hydration errors suck: they don’t always make sense.

So why does there appear to be no HTML rendered on the server according to the diff? Given that React threw a nonsensical hydration error for invalid HTML, Sentry can only make a best-effort guess as to what the problem is. Usually, if one event has a diff that doesn’t make sense, another event may be more helpful. The bottom line is that when React throws a hydration error, there’s a problem that needs fixing. And because React doesn’t tell us the details needed to fix the problem in production, Sentry fills in the blanks on the hydration error diff tools as much as possible so you can better debug the problem.

Does creating hydration error issues and diffs increase my Sentry bill?

No. If you’re already using Session Replay, you get automatic grouped hydration error issues for free. Hydration error issues in Sentry are generated from Replays and their associated data, so have no impact on your error quota, either. Additionally, you’ll also get alerted on hydration errors by default.

Bonus tip: level-up your debugging by unmasking non-sensitive data in replays

If you’re using Session Replay, you might have noticed that it masks all text content with * and blocks all media elements on the client by default, before it is sent to Sentry. In this article, the examples shown in the hydration errors images show text rather than asterisks, due to how the Session Replay SDK was configured.

If you’re working on a content-based website that’s free of personally identifiable information (PII), you can disable the default text masking and image blocking by configuring the maskAllText and blockAllMedia configuration options in the Session Replay initialization.

Sentry.replayIntegration({
maskAllText: false,
blockAllMedia: false,
});

This can be really helpful in debugging fake hydration errors (that are actually invalid HTML errors) like the one demonstrated in this article. Note: Only use this if your site has no sensitive data or if you’ve already set up other options for masking or blocking actual sensitive data. Read more about Session Replay privacy configuration on the Sentry docs.

Debuggability is key

Hydration errors in production have always been a bit of a mystery, without any practical way to deal with and debug them. With the Sentry Replay SDK, you now get the HTML diffs and as much context as possible with each hydration error, helping you to debug and fix things faster. And whilst this ultimately helps you as a developer, it benefits everyone else as well: stakeholders, clients, and most importantly — your users. Now, go fix those bugs.

Originally posted on blog.sentry.io

Like weird newsletters?

Join 271+ subscribers in the Weird Wide Web Hole to find no answers to questions you didn't know you had.

Subscribe

Salma is looking at you, with a rather large smile. She's pointing across herself up to her left, with a very tatooed arm. She's wearing a black shirt and black rimmed glasses.

Salma Alam-Naylor

I'm a live streamer, software engineer, and developer educator. I help developers build cool stuff with blog posts, videos, live coding and open source projects.

Related posts

2 Jul 2024

Your bad LCP score might be a backend issue

This is the best way to debug slow web pages.

Web Dev 8 min read →

19 Aug 2024

How to make your web page faster before it even loads

Perhaps you could use your new-found knowledge on DNS to wow people at all the cool parties you probably attend.

Web Dev 14 min read →