question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using overridden _app & _document throws "ReferenceError: document is not defined"

See original GitHub issue

💬 Questions and Help

My _app.js:

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';

import { ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';

import theme from '@/components/theme';

const App = ({ Component, pageProps }) => {
  useEffect(() => {
    // Remove the server-side injected CSS (need this to stop HMR from showing React warnings)
    const jssStyles = document.querySelector('#jss-server-side');

    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  });

  return (
    <>
      <Head>
        {/* Custom header */}
      </Head>

      <ThemeProvider theme={theme}>
        <CssBaseline />

        <Component {...pageProps} />
      </ThemeProvider>
    </>
  );
};

App.propTypes = {
  Component: PropTypes.elementType.isRequired,
  pageProps: PropTypes.object.isRequired,
};

export default App;

My _document.js:

import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';

class Doc extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          {/* Custom header */}
        </Head>

        <body>
          <Main />

          <NextScript />
        </body>
      </Html>
    );
  }

  static async getInitialProps(context) {
    // Render app and page and get the context of the page with collected side effects.
    const sheets = new ServerStyleSheets();
    const originalRenderPage = context.renderPage;

    // THIS SEEMS TO BE CAUSING ISSUES IN JEST?
    context.renderPage = () =>
      originalRenderPage({
        enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
      });

    const initialProps = await Document.getInitialProps(context);

    return {
      ...initialProps,
      // Styles fragment is rendered after the app and page rendering finish.
      styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
    };
  }
}

export default Doc;

NB this enables MaterialUI to play nice with the NextJS stack.

My index.test.js:

/**
 * @jest-environment jsdom
 */

import { getPage } from 'next-page-tester';
import { screen, waitFor } from '@testing-library/react';

describe('IndexPage', () => {
  it('shows index page', async () => {
    const { render } = await getPage({ route: '/', useDocument: true });

    render();

    // Some other stuff ...
  });
});

When running the test:

$ jest
 FAIL  test/index.test.js (27.528 s)
  IndexPage
    ✕ shows index page (13297 ms)

  ● IndexPage › shows index page

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
    Consider using the "jsdom" test environment.
    
    ReferenceError: document is not defined

      55 |
      56 |     context.renderPage = () =>
    > 57 |       originalRenderPage({
         |       ^
      58 |         enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
      59 |       });
      60 |

The error is the same whether or not I include the @jest-environment docblock in the test file.

If I omit useDocument: true from the getPage() options I get the failure a bit later, but with the same error:

$ jest
 FAIL  test/index.test.js (19.88 s)
  IndexPage
    ✕ shows index page (9129 ms)

  ● IndexPage › shows index page

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/en/configuration#testenvironment-string.
    Consider using the "jsdom" test environment.
    
    ReferenceError: document is not defined

      10 |     const { render } = await getPage({ route: '/' });
      11 |
    > 12 |     render();
         |     ^
      13 |
      14 |     expect(screen.getByRole('progressbar')).toBeInTheDocument();
      15 |

NB I’ve patched jest according to https://github.com/toomuchdesign/next-page-tester#optional-patch-jest. I’m running jest v26.6.3 .

I’m probably missing something obvious. Anyone have an idea?

Thanks!

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:8
  • Comments:10

github_iconTop GitHub Comments

1reaction
domhedecommented, Mar 23, 2021

Hello 👋 @Meemaw I too am getting a similar error.
This is a demo repo: https://github.com/domhede/next-page-tester-demo

0reactions
jyk2000commented, Apr 28, 2021

For anyone having the error coming from styled-jsx selectFromServer function, I fixed the issue by changing .babelrc I still have another issue to fix but at least the “document not defined” part, I passed.

{
  "presets": ["next/babel"],
  // this is what you're adding:
  "env": {
    "test": {
      "presets": [
        [
          "next/babel",
          {
            "styled-jsx": {
              "babel-test": true
            }
          }
        ]
      ]
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using overridden _app & _document throws "ReferenceError ...
I had the same problem (using just a custom document), and managed to fix it by upgrading react and react-dom to version 17....
Read more >
ReferenceError: document is not defined in JavaScript
The "ReferenceError: document is not defined" error is thrown when the code tries to access the document object, but the object is not...
Read more >
NextJS: ReferenceError: document is not defined
I am creating a npm package for myself. I am using webpack, tailwind and storybook to create a UIKit. It work fine on...
Read more >
How to fix ReferenceError: Document is not defined ... - Sabe.io
In this post, we looked at the most common reasons that causes the document reference error in JavaScript. The main culprits are using...
Read more >
this - JavaScript | MDN
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found