82

I get the a "ReferenceError: document is not defined" while trying to

var body = document.getElementsByTagName("body")[0];

I have seen this before in others code and didn't cause any trouble. Why is it now? The companied HTML page is just a div inside the body.

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="css/quiz.css" />
    <script type="text/javascript" src="js/quiz.js"></script>
</head>
<body>

    <div id="divid">Next</div>

</body>
</html>

the code is the following:

(function(){
        var body = document.getElementsByTagName("body")[0];

        function Question(question, choices, correctAns) {
            this.question = question;
            this.choices = choices;
            this.correctAns = correctAns;
        }

        Question.prototype.checkAns = function(givenAns){
            if (this.correctAns === givenAns) {
                console.log("OK");
            }
        };

        function Quiz() {
            this.questions = [];
        }

        Quiz.prototype.showAllQuestions = function(){
            this.questions.forEach(function(questions){
                console.log(questions.question);
            });
        };

        Quiz.prototype.showQuiz = function(){
            this.questions.forEach(function(questions){

                for (var i=0; i < questions.choices.length; i+=1) {
                    body.innerHTML(
                            "<input type=\"radio\" name=\"sex\" value=\"male\">" 
                            + questions.choices[i] + "<br>");
                }

            });
        };

        var q1 = new Question("What is red?", ["Color","Animal","Building"],1);
        var q2 = new Question("Most popular music?", ["Latin","Pop","Rock"],2);
        var quiz = new Quiz();

        quiz.questions.push(q1);
        quiz.questions.push(q2);
        quiz.showAllQuestions();


        })();

Try the whole code in this link HERE

2
  • Show your HTML code Commented Jul 9, 2014 at 7:39
  • 1
    The code you link to does not throw that error Commented Jul 9, 2014 at 9:49

13 Answers 13

73

This happened with me because I was using Next JS which has server side rendering. When you are using server side rendering there is no browser. Hence, there will not be any variable window or document. Hence this error shows up.

Work around :

If you are using Next JS you can use the dynamic rendering to prevent server side rendering for the component.

import dynamic from 'next/dynamic'

const DynamicComponentWithNoSSR = dynamic(() => import('../components/List'), {
  ssr: false
})

export default () => <DynamicComponentWithNoSSR />

If you are using any other server side rendering library. Then add the code that you want to run at the client side in componentDidMount. If you are using React Hooks then use useEffects in the place of componentsDidMount.

import React, {useState, useEffects} from 'react';

const DynamicComponentWithNoSSR = <>Some JSX</>

export default function App(){

[a,setA] = useState();
useEffect(() => {
    setA(<DynamicComponentWithNoSSR/>)
  });


return (<>{a}<>)
}

References :

  1. https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr
  2. https://reactjs.org/docs/hooks-effect.html
Sign up to request clarification or add additional context in comments.

2 Comments

I'm using pureJS (no libraries), and rn just staring at the console like "what.". Any help?
This is the right answer if you're using Next.js
8

It depends on when the self executing anonymous function is running. It is possible that it is running before window.document is defined.

In that case, try adding a listener:

window.addEventListener('load', yourFunction, false);
// OR: 
window.addEventListener('DOMContentLoaded', yourFunction, false);
    
yourFunction () {
  // some code
}

Update: (after the update of the question and inclusion of the code)

Read the following about the issues in referencing DOM elements from a JavaScript inserted and run in head element:

3 Comments

IIRC the document global variable is always defined, even before the DOM elements have fully loaded.
There are instances (like in an addon) that a JS can run before DOM is created. At the time of posting, full code was not available to check.
Ah, that would make sense.
7

You may deactivate ssr for the whole component (check Trect's answer), but it's overkill since you only need to skip one line in ssr.

You should only check if document is defined (determining if the function is called server-side -no document- or client-side -document defined-):

if (typeof document === 'undefined') {
    // during server evaluation
} else {
    // during client's browser evaluation
}

In your case, you don't need to do anything server-side, you may do something like:

var body = null;

if (typeof document !== 'undefined') {
    // will run in client's browser only
    body = document.getElementsByTagName("body")[0];
}

Comments

4

Try adding the script element just before the /body tag like that

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" type="text/css" href="css/quiz.css" />
</head>
<body>

    <div id="divid">Next</div>
    <script type="text/javascript" src="js/quiz.js"></script>
</body>
</html>

Comments

3

Adding "defer" attribute to <script> tag can also fix it.

<script defer src="yourScript.js"></script>   

In this case you can keep <script> inside of <head>.

Comments

2

This happened mostly to front-end developers using javascript and trying to execute their code with node. I know you must have tried to use node or any other run-time environs to execute your code. but sadly, in Node, the document object or window object does not exist, instead, we have modules. this means if your script contains Document.getElement, or you try to operate on your DOM, you are gonna get this error. Same with the window object,e.g Window.alert("Hi") , and The import e.g import as File from "./MyFile", you will definitely get an error while trying to execute your code with node because Node is a Server-Side Javascript Run-Time Environment. In same sense, we have the global objects, if you must have heard of it like (console,this) are all global variables.

Comments

-1

This issue happened when you call the eliment which didn't created yet You called the body and it's component in <head > Call the file in the end of< body > Just before </body> will solve it.

Comments

-1

If you want to access the HTML DOM Document Object directly in Typescript, this implies that you will use the browser as the environment and have the Type Script tooling generate the code behind, while you use a code editor like VsCode to debug through your typescript.

const document: Document = document as Document;

or if you want to use it into a class just do:

class ExampleClass {
   private document: Document;
   private btn: HTMLElement;

   constructor() {
       this.document = document as Document;
   }

   public exampleOfGettingAButton(): void {
       this.btn = this.document.getElementById("my-btn");
   }
}

Comments

-1

Problem: I got this error while using tailwind components from [tailwind-elements]. (https://tailwind-elements.com/)

Explanation: The error is caused because NextJs renders the page in the server only and in the server document (document is used inside tailwind-elements)is not available.

Solution: Use a dynamic route from NextJS.

import dynamic from "next/dynamic";

const {} = dynamic(import("tw-elements"), { ssr: false });

1 Comment

I had similar case in SvelteKit and disabling SSR helped vanishing this document is not defined error
-1

Javascript loads before the DOM content, that’s why you get undefined. You could try to add the attribute ‘defer’ to the script tag:

<script src="./index.js" defer></script>

Comments

-1

Just check javascript file is in the folder or not. For Example:

My 'javascript' file and my 'html' file are in the same folder. So I don't need to type a subfolder path. I can write just : "first.js"

<body>
    <script src="first.js"></script>
</body>

But İf your 'javascript' and your 'html' file are in different folders.You have to use subfolder path. For example:

<body>
    <script src="js/first.js"></script>
</body>

I hope this information is useful to you.I was getting this error because I'm not paying attention to it.

Hoşçakalın :)

Comments

-1

When you're trying to execute plain JavaScript using the command node quiz.js from the console, you're attempting to run the JavaScript in a Node.js environment. However, the document object is not available in Node.js environment, hence resulting in an error. To view the output of JavaScript code in a browser, you can right-click, select "Inspect", and navigate to the console tab to see the output of your JavaScript code.

Comments

-10

try: window.document......

var body = window.document.getElementsByTagName("body")[0];

1 Comment

ReferenceError: window is not defined

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.