Cover Image for Quickly fix Gatsby rehydration issues

Quickly fix Gatsby rehydration issues

You've been building your site for hours, and spit-shone every last bit. It's time to hit gatsby build and get it flung up online.

If you're unlucky, on the build version you may note something like the nav turning the wrong colour when you scroll. This can be earth-shatteringly annoying to fix if you're not aware of the kinks introduced by Gatsby's server-side rendering.

Gatsby pre-renders all the site content using Node.js, and therefore data/methods/objects that are available to the client aren't at the build stage - e.g. the window object.

This process allows for many of the features we all love about Gatsby - such as speed - but when it comes into contact with dynamic content from the client-side strange bugs can be introduced.

So after we have desiccated our site on the server-side, we have to rehydrate it in a controlled manner.

This is a quick fix using React hooks.

Make a reusable hook:

1 import { useState, useEffect } from "react";
2
3 const useIsClient = () => {
4 const [isClient, setClient] = useState(false);
5 const key = isClient ? "client" : "server";
6
7 useEffect(() => {
8 setClient(true);
9 }, []);
10
11 return { isClient, key };
12 };
13
14 export default useIsClient;
15

In the above, the useEffect hook only runs after the first render, so in the build process setClient will not be set to true.

So when the following is put into your component, nothing will be 'pre-rendered' on the server-side, but only on rehydration. Returning null saves the user from seeing flickerings from an incorrectly rendered state.

1 import useIsClient from "../utils/useIsClient";
2
3 export default function Nav() {
4 const { isClient, key } = useIsClient();
5
6 if (!isClient) return null;
7
8 return <NavComponent key={key} />;
9 }
10

By passing key to the key prop we can tell React what we need to rerender.

Used judiciously this should solve your woes.

Simple ay?

The Gatsby team are working on making this issue quicker to debug by enabling server-side rendering in develop - you can follow that discussion here.