Hydration Error in Next.js: What is it and how to solve it

Introduction

Before moving on to the main topic, I want to step back and explain Next.js. Next.js is an open-source React framework that facilitates the building and deployment of server-rendered React applications. Developed by Vercel, Next.js seamlessly combines the simplicity of React with powerful features designed for scalability and optimal performance. If you want to read more about the Next.js framework and how it enhances the web app performance compared to a regular React.js application, please refer to my previous blog by clicking here

Prerequisites

There is only one prequisite for proceeding with this blog that is to know "What is client-side rendered page and server-side rendered page in Next.js". Don't worry if you do not know what they are, I will explain it here but before please make sure to go through my previous blog, click here.

By default, all the pages in Next.js 14 are server-side rendered which means the HTML will be first rendered on the server and then sent to client to render it on the screen.

๐Ÿ’ก
The problem with server side rendered pages or components is that, you cannot use user interactions code snippets like onClick or onMouseDown, or any client-side libraries etc.

To include user interactions, we need to make the page or component as client-side rendered. How can we make our component as client-side, we just to put

"use client"

at the top of our component to make it client-side rendered. This should cover the prerequisite for my article.

What is Hydration Error?

The Hydration failed error in Next.js occurs when the initial UI of a page does not match what was rendered on the server. This can happen for a variety of reasons, such as changes to the markup or the use of client-side libraries that are not compatible with Next.js.

๐Ÿ’ก
Even if we make our component as client component using "use client", still the page will be rendered first on the server itself.

When this error occurs, the page will not render correctly, and the user may see a blank page or an error message.

Reproducing hydration error through a client component

  1. Create a new Next.js app or clone from my repository by clicking here

  2. Create a new folder called components inside the app folder

  3. In components folder, create a new file called as HydrationDemo.tsx

  4. In HydrationDemo.tsx , paste this code:

"use client";
import React from "react";

const HydrationDemo = () => {
  const i = Math.random();
  return (
    <>
      <div>The random value of i is {i}</div>
    </>
  );
};

export default HydrationDemo;
  1. Import this component inside the page.tsx and run the application, after opening the localhost:3000, you can see this error:

How to solve this error now?

To solve this error first remember a point.

๐Ÿ’ก
Even if we make our component as client component using "use client", still the page will be rendered first on the server itself.

So when Next.js renders this component on the server, the random that is generated on server will be different than the value that is generated on the client side so this causes hydration error.

To solve this, we gotta render the value only when the component is client-side completed , to achieve this, copy the below code:

"use client";
import React, { useEffect, useState } from "react";

const HydrationDemo = () => {
  const [isClient, setIsClient] = useState<boolean>(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  const i = Math.random();
  return <>{isClient && <div>The random value of i is {i}</div>}</>;
};

export default HydrationDemo;

Here, we are using a state variable to know if the component is client side yet or not. We useEffect Hook to change the isClient state to true when the component is mounted. We render the value of i only when the isClient is true, this forces the Next.js compiler to use value that is generated on the client-side and does not compare when the component is server-side.

Some ways to solve and prevent Hydration error

  1. Check the markup: Make sure that the markup of your page matches what was rendered on the server. This includes checking for any changes that may have been made to the HTML, CSS, or JavaScript.

  2. Use a different rendering strategy: If you are using server-side rendering (SSR), you can try using client-side rendering (CSR) instead. CSR will not suffer from hydration errors, but it will not be as performant as SSR.

  3. Use the suppressHydrationWarning prop: If you are using a client-side library that is not compatible with Next.js, you can use the suppressHydrationWarning prop to silence the hydration warning. This will prevent the error from being displayed, but it will not fix the underlying problem. Not recommended to use this but if the error does not affect the functionality of the application then this can be used.

Conclusion

Implementing best practices for handling server-rendered content and client-side modifications can help prevent hydration errors and improve the overall performance of Next.js applications. By following these guidelines, developers can create more efficient and stable web applications that provide a superior user experience.

To understand hydration error more in detail, you can refer to the official Next.js documentation by clicking here. They have a beautiful and well structured course to learn about Next.js in depth. To follow along with me on "Next.js 14 Learning path", click here and to get access to my GitHub repository that I am using in this series, click here.

For any query, you can get in touch with me via LinkedIn and twitter.Leave all your comments and suggestions in the comment section. Let's connect and share more ideas.

Happy coding!

0
Subscribe to my newsletter

Read articles from Gautham R Vanjre directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Gautham R Vanjre
Gautham R Vanjre

SDE-1 @HashedIn by Deloitte | Passionate about Web and Mobile Development | ๐ŸŒ Turning ideas into digital solutions | #JavaScript #React #NodeJS #WebDev #Typescript #MobileDev ๐Ÿš€