4 Solutions – ReferenceError: document is not defined in Next.js

While working on Next.js server-side rendered application, One error often encountered by developers is the “ReferenceError: document is not defined”.

In this article, we will take a closer look at this error, understand why it occurs, and provide various possible solutions, along with sample code snippets, to help resolve it effectively.

Next.js is a popular React framework that enables developers to create server-rendered React applications very easily. While it offers several benefits, such as automatic code splitting and server-side rendering, it also presents some unique challenges.

One common issue developers face is the “document is not defined” error and “window is undefined”, which occurs when trying to access the ‘document’ or ‘window’ object in a server-rendered environment.

In the following sections, we’ll explore the reasons behind this error and provide 4 possible solutions to fit in various sites based on your application requirements with examples.

 

Why do we face the “document is not defined” error in Next.js?

The “document is not defined” error occurs because the ‘document’ object resides in the browser’s Window object and is not available in a server-rendered environment. Next.js, by default, renders pages on the server side, and the ‘document’ object is not accessible during the initial rendering of the application.

 

What error is shown?

This error appears in the console when you try to access the ‘document’ object in a Next.js application. The error message looks like this:

ReferenceError: document is not defined

 

Solutions for this error

We have understood why this issue shows up. Next, we will discuss multiple ways to easily resolve the issue using various methods:

 

1 – By using the componentDidMount lifecycle method

One way to resolve this issue is by using the componentDidMount lifecycle method. This hook is only executed on the client side. This ensures that the ‘document’ object is available when the code runs. Here is an example:

import React, { Component } from 'react';

class DocumentHandler extends Component {
  componentDidMount() {
    // Access the document object here
    console.log(document.title);
  }

  render() {
    return <div>Example Component</div>;
  }
}

export default DocumentHandler;

 

2 – Using dynamic imports

The next solution is to use dynamic imports, which allows to load a module or component only on the client side. Here’s an example using the ‘next/dynamic’ package:

import dynamic from 'next/dynamic';

const ClientSideComponent = dynamic(
  () => import('./ClientSideComponent'),
  { ssr: false }
);

function MyApp() {
  return (
    <div>
      <ClientSideComponent />
    </div>
  );
}

export default MyApp;

 

3 – Utilizing the useEffect Hook

For functional components, you can use the useEffect Hook to run side effects, such as accessing the ‘document’ object, only after the component has been rendered on the client side. Here’s an example:

import React, { useEffect } from "react";

function DocumentHandler() {
  useEffect(() => {
    // Access the document object here
    console.log(document.title);
  }, []);

  return <div>Example Component</div>;
}

export default DocumentHandler;

 

4 – Server-side rendering with getServerSideProps

In some cases, you may want to use server-side rendering (SSR) to fetch data before rendering your page. To achieve this, we can use the getServerSideProps function provided by Next.js. By doing so, we can ensure that the component is only rendered on the server side, avoiding the “document is not defined” error. Here‘s an example:

// pages/MyPage.js
import React from 'react';

function MyPage({ serverData }) {
  return <div>Server Data: {serverData}</div>;
}

export async function getServerSideProps() {
  // Fetch data from an API or other server-side data source
  const serverData = await fetchData();

  return {
    props: {
      serverData,
    },
  };
}

export default MyPage;

 

Conclusion

The “ReferenceError: document is not defined” error in Next.js can be resolved using various approaches, such as the componentDidMount lifecycle method, dynamic imports, the useEffect Hook, or server-side rendering with getServerSideProps. You can deploy any solution from the above-mentioned methods based on your requirements and application arch.

Leave a Comment

Your email address will not be published. Required fields are marked *