Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.js: document is not defined

I am trying to create a payment form where people can pay but I keep getting this error.

document is not defined

I'm using Next.js. Please see my code below:

import React from "react";
import {Elements, StripeProvider} from 'react-stripe-elements';
import CheckoutForm from '../../components/Payment/CheckoutForm';
import { useRouter } from 'next/router';


var stripe_load = () => {
    var aScript = document.createElement('script');
    aScript.type = 'text/javascript';
    aScript.src = " https://js.stripe.com/v3/";

    document.head.appendChild(aScript);
    aScript.onload = () => {

    };
};

function Payment({host}) {
    const key = host.includes('localhost') ? 'test' : 't';

    stripe_load();

    const router = useRouter();

    return (
        <div className="Payment Main">
            <StripeProvider apiKey={key}>
                <Elements>
                    <CheckoutForm planid={router.query.id}/>
                </Elements>
            </StripeProvider>
            <br/>
            <br/>
            <p>Powered by Stripe</p>
        </div>
    );
};


Payment.getInitialProps = async ctx => {
    return { host: ctx.req.headers.host }
};

export default Payment
like image 941
Chris Hansen Avatar asked Mar 11 '20 04:03

Chris Hansen


People also ask

How do you fix document is not defined in js?

js you can fix this problem by wrapping the code you run in a conditional. The code might be running in both situations - frontend, when you navigate to a page using a link, and server-side if you require server-side into your page, for example by running getServerSideProps() .

Can you use document in node js?

Yes, there are ways to create documents in Node.

What is next JS used for?

Next. js is a JavaScript framework created by Zeit. It lets you build server-side rendering and static web applications using React. It's a great tool to build your next website. It has many great features and advantages, which can make Nextjs your first option for building your next web application.

Why is my document not defined in Node JS?

There are specific reasons for the “ReferenceError: document is not defined” error, such as: Misspelled the global variables; global variables should be in lower cases. To solve the“ReferenceError: document is not defined” error in Node.js, make sure you don’t use the document global variable.

What is the nextnext JS framework?

Next.js is a Rea c t framework with pre-rendering abilities. This means that for every page, Next.js will try to generate the HTML of the page for better SEO and performance. This is why, if you’re trying to do this: console.log ("scroll!") Then it will fail with “ReferenceError: document is not defined”:

Why does nextnext JS throw an error?

Next js executes this code on the server side and that's why the error is thrown. In this tutorial I'll show you three ways on how to solve this issue. Since the window is part of the browser, we can wrap our code inside an if statement.

What is the difference between Node JS and HTML?

In node.js, you don't have DOM APIs (window, document, document.getElementById,...), the thing can be only have when your HTML is rendered in a thing called windows of Browsers. So next.js use node.js to run JS code and take result to render HTML file. But in node.js, nothing is windows of Browser. My English is quite bad.


4 Answers

I think, in server rendering mode, the document is undefined. You should be able to use it inside class lifecycle methods or useEffect

import React, {useEffect} from "react";
import {Elements, StripeProvider} from 'react-stripe-elements';
import CheckoutForm from '../../components/Payment/CheckoutForm';
import { useRouter } from 'next/router';


var stripe_load = () => {
    var aScript = document.createElement('script');
    aScript.type = 'text/javascript';
    aScript.src = " https://js.stripe.com/v3/";

    document.head.appendChild(aScript);
    aScript.onload = () => {

    };
};

function Payment({host}) {
    const key = host.includes('localhost') ? 'test' : 't';

    useEffect(() => {
      var aScript = document.createElement('script');
       aScript.type = 'text/javascript';
       aScript.src = " https://js.stripe.com/v3/";

       document.head.appendChild(aScript);
       aScript.onload = () => {

       };
    }, [])
    //stripe_load();

    const router = useRouter();

    return (
        <div className="Payment Main">
            <StripeProvider apiKey={key}>
                <Elements>
                    <CheckoutForm planid={router.query.id}/>
                </Elements>
            </StripeProvider>
            <br/>
            <br/>
            <p>Powered by Stripe</p>
        </div>
    );
};


Payment.getInitialProps = async ctx => {
    return { host: ctx.req.headers.host }
};

export default Payment
like image 186
san Avatar answered Oct 01 '22 07:10

san


You need to wrap your document using validator process.browser, because this document is belong to client side, and the error occured when nextjs render in server side.

var stripe_load = () => {
    if (process.browser) {
        var aScript = document.createElement('script');
        aScript.type = 'text/javascript';
        aScript.src = " https://js.stripe.com/v3/";

        document.head.appendChild(aScript);
        aScript.onload = () => {

        };
    }
};
like image 29
Darryl RN Avatar answered Oct 01 '22 06:10

Darryl RN


For example, when the module includes a library that only works in the browser. Some times dynamic import can solve this issue.

Take a look at the following example:

import dynamic from 'next/dynamic'

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

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
like image 16
Partho Avatar answered Oct 01 '22 07:10

Partho


for me, this error occurs from lots of mistakes: first, you have to use

if (typeof window !== "undefined") {

for every window. and document. and especially for localStorage. functions (my self forgot to use this if clause for localStorage.getItem and the error didn't fix)

another problem was the import of the line below which was totally wrong!:

import {router} from "next/client";
like image 15
Ali Avatar answered Oct 01 '22 05:10

Ali