ReferenceError: document is not defined (in plain JavaScript)

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

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 ocde

}

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:
- “getElementsByTagName(…)[0]” is undefined?
- Traversing the DOM