Fixing Hydration Errors From Netlify Forms
I recently upgraded this site's version of Gatsby for the first time, from v2.31.1 to v5.3.1. I skimmed through some of the migration guides, v2 to v3, v3 to v4 and v4 to v5, but decided to do the upgrade in one fell swoop. It was relatively painless, with the largest effort going towards migrating from the "gatsby-image" APIs to the newer "gatsby-plugin-image".
When I was satisfied with the changes, and confirmed there were no glaringly obvious issues, I pushed directly to master, which is a great habit to get into. This triggered a build on Netlify and after a couple of minutes, my changes were live. Only now I did see an issue.
<iframe width="560" height="315" loading="lazy" src="https://www.youtube.com/embed/KQKkAIr8uhQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
That is what I saw when I loaded the homepage. In Chrome Dev Tools, I noticed several error messages from React. The error messages were numbered, but weren't detailed because React's production builds are designed to be as lean as possible. It was screaming about error 418 and error 423, which both indicate hydration problems. Normally, I would just ignore these errors, which is another great habit, but it was completely ruining the animations. I needed to figure out why this was happening.
Gatsby v5 requires React v18, which introduced stricter hydration errors. Hydration errors occur when there is a mismatch between the DOM React spit out on the server and on the client. I next needed to figure out which of my components were causing these mismatches to occur.
There was no easy way to debug this, because I did not get any hydration errors during development, even after adding DEV_SSR: true as a flag in my Gatsby config. What was even stranger, was I didn't see the errors while serving a production build on my machine, but only when served through Netlify. I even tried to use the Netlify CLI to deploy my locally built code to Netlify's CDN. Still, the error persisted, only on Netlify.
I was scratching my head, and began the painstaking process of removing components one by one and waiting for a full build and deploy to try and track down the issue. After no success, I eventually came up with the idea to check the initial markup served locally vs served via Netlify. I used a tool call diffchecker and found my issue. As it turns out, Netlify parses your HTML post build and injects an additional input tag. All I needed to do was to add that same input to my component, so it would be there on the client during hydration. Just one line of code to fix the problem, line 78.
I was satisfied, patted myself on the back and pushed directly to master one last time. Another bug squashed.
The featured image of this blog post was generated by DALL-E 2, given the input:
a very dehydrated person seated on an office chair browsing the internet on their desktop computer in a cartoon style
These are the other 3 images generated: