How to solve the document is not defined error

By

Learn how to fix the 'document is not defined' error in Node.js or Next.js: document is browser-only, so guard it with a typeof window check.

~~~

The “ReferenceError: document is not defined” error happens when you access document in Node.js or in the server-side part of a tool like Next.js. The fix is to make sure the code that uses document only runs in the browser.

document is an object that’s made available by the browser, and it’s not available in a server-side JavaScript environment.

I describe the document object is details in my extensive DOM Document Object Model guide.

Why does this error happen?

The browser gives you document as the entry point to the page content. A server has no page, so the object does not exist there.

This line works in the browser and crashes in Node:

document.title = 'Dashboard'
// ReferenceError: document is not defined

Fixing it in Node.js

With Node.js in particular there’s no way to workaround the problem - you must find the particular place where document is used, and revisit the code to figure out why you are accessing the document object.

You are running frontend code in a backend environment.

A common cause is importing a library that was written for the browser, like a charting or animation library. Move that code to the frontend, or look for a server-friendly alternative.

Fixing it in Next.js

In Next.js the same component code runs in two places. It runs in the browser when you navigate to a page using a link, and it runs server-side when Next.js renders the page, for example when you use getServerSideProps().

In this case, you can limit the reference to document into a conditional that checks if the window object is available, like this:

if (typeof window !== 'undefined') {
  //here `window` is available, so `window.document` (or `document`) is available too
}

And this will fix your problem, since you only run anything inside the conditional in a browser environment.

Alternatively, you can put the code inside a useEffect() callback. Effects never run during server-side rendering, only in the browser after the component mounts:

useEffect(() => {
  document.title = 'Dashboard'
}, [])

Be careful with the check

Write the check exactly as typeof window !== 'undefined'.

Checking window !== undefined looks equivalent, but it’s not. Referencing an identifier that doesn’t exist throws a ReferenceError, so on the server that check crashes with “window is not defined” - the same class of error you’re trying to fix. The typeof operator is safe to use on names that don’t exist.

The same fix applies to the “window is not defined” and “localStorage is not defined” errors. They all mean the same thing: browser-only code is running on the server.

~~~

Related posts about js: