ReferenceError: document is not defined in JavaScript

avatar
Borislav Hadzhiev

Last updated: Mar 2, 2024
4 min

banner

# ReferenceError: document is not defined in JavaScript

The "ReferenceError: document is not defined" error occurs for multiple reasons:

  1. Using document in Node.js.
  2. Using document on the server (e.g. server-side rendering in Next.js).
  3. Misspelling the document global variable (should be all lowercase).

referenceerror document is not defined

# The document object is not available in Node.js

Node.js does not provide a browser environment, it's a server-side runtime, so we can't use the document variable in Node.

Trying to run the following code in Node.js causes the error.

index.js
// โ›”๏ธ ReferenceError: document is not defined console.log(document.getElementsByClassName('my-class'));

The document relates to the document object which represents a web page that is loaded in the browser.

The quickest way to solve the error is to use an if statement.

index.js
if (typeof window !== 'undefined') { // ๐Ÿ‘‰๏ธ can use document here console.log('You are on the browser') console.log(document.title) console.log(document.getElementsByClassName('my-class')); }
The code for this article is available on GitHub

The if block only runs in a browser environment where the document object is available.

# Move your JS script tag to the bottom of the body tag

If you got the error in the browser, try to move your JS script tag to the bottom of the body tag.

index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <!-- Your HTML here --> <!-- ๐Ÿ‘‡๏ธ Script at bottom of body --> <script type="module" src="index.js"></script> </body> </html>

move js script tag to bottom of body tag

The code for this article is available on GitHub

You might have some add-ons that are run before the DOM is created.

# Check if you are on the browser before accessing document

If you get the error in Node.js, e.g. when using Next.js and you need to check if you are on the browser (can use document) or on the server (can't use document), you can do this in the following way.

index.js
if (typeof window !== 'undefined') { // ๐Ÿ‘‰๏ธ can use document here console.log('You are on the browser') console.log(document.title) console.log(document.getElementsByClassName('my-class')); } else { // ๐Ÿ‘‰๏ธ can't use document here console.log('You are on the server') }

check if you are on the browser before accessing document

We check if the global window variable doesn't have a type of undefined. If the window global is defined, we are on the browser and can use the document variable.

# Access the document object in your useEffect hook in React and Next.js

If you got the error in React.js, move the code that uses document in your useEffect hook.

The useEffect hook runs after React renders your component in the browser environment, so you can safely access the document object in useEffect.

App.js
import {useEffect} from 'react'; export default function App() { useEffect(() => { console.log(document.title); console.log(document.getElementById('root')); }, []); return ( <div> <h2>hello world</h2> <button onClick={() => { console.log(document.title); }} > Log title </button> </div> ); }

If you are trying to use the document object to access an element in a React.js application, you should probably use a ref instead.

App.js
import {useEffect, useRef} from 'react'; export default function App() { const ref = useRef(null); // ๐Ÿ‘‡๏ธ check if element is focused on mount useEffect(() => { if (document.activeElement === ref.current) { console.log('element has focus'); } else { console.log('element does NOT have focus'); } }, []); return ( <div> <input ref={ref} autoFocus type="text" id="message" name="message" /> </div> ); }

We set the ref prop on the input element, so we can access the element in our useEffect hook as ref.current.

When we pass a ref prop to an element, e.g. <input ref={myRef} />, React sets the .current property of the ref object to the corresponding DOM node.

# Using an if statement to check if you are on the browser

If that doesn't work, you have to use an if statement to check if you're on the browser (can use document) or server (can't use document).

index.js
if (typeof window !== 'undefined') { // ๐Ÿ‘‰๏ธ can use document here console.log('You are on the browser') console.log(document.title) console.log(document.getElementsByClassName('my-class')); } else { // ๐Ÿ‘‰๏ธ can't use document here console.log('You are on the server') }

using if statement to check if you are on the browser

The code for this article is available on GitHub

The if block only runs if the window object is not undefined (we are on the browser).

The document object can safely be accessed on the browser, so you can access properties on the object in the if block.

If the else block runs, the code is not in a browser environment and doesn't have access to the document object.

# Make sure you haven't misspelled document

Another common cause of the error is misspelling document (it's all lowercase).

index.js
// โ›”๏ธ ReferenceError: Document is not defined const el1 = Document.getElementById('my-id'); console.log(el1);

The code sample uses Document (capital D) instead of document which caused the error.

Instead, the object is spelled in all lowercase.

index.js
const el1 = document.getElementById('my-id'); console.log(el1);
The code for this article is available on GitHub

# Conclusion

To solve the "ReferenceError: document is not defined" error, make sure:

  1. You aren't trying to access the document object in Node.js.
  2. You aren't using document on the server (e.g. server-side rendering in Next.js).
  3. You haven't misspelled the document global variable (should be all lowercase).
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev