Gatsby window not available during server side rendering build error

Viewed 8453

I am trying to build my Gatsby site to deploy to production, but I have run into an issue which I believe is related to one line of code within my application where I use window to redirect to an external url that is retrieve from a GET request made on a button click. I tried to read through the documentation on this issue and attempted to use their window check conditional, but my redirect either didn't work or I received an error related to Can't resolve 'module'. Is there an alternative route to either replacing the use of window all together or fixing why this runs during build and causing the error?

Error:

failed Building static HTML for pages - 2.611s

 ERROR #95312

"window" is not available during server side rendering.

Error for code checking for window:

  WebpackError: ReferenceError: window is not defined

Code:

authClick(e) {
        e.preventDefault();
        this.setState({ authorizing: true }, ()=> {
            axios.get(auth_url)
                .then((res) => {
                    this.setState({
                        authorizing: false
                    })

                    window.location.replace(res.data) // Window call

                    // Attempt to fix the issue based on documentation
                    // if (typeof window !== `undefined`){ 
                    //     const module = require("module")
                    //     window.location.replace(res.data) 
                    // }
                }).catch((err) => {
                    console.log(err)
                })
        });
    }

// Component
    <button className="inline-flex items-center" onClick={this.authClick} disabled={this.state.authorizing}>
    Auth
    </button>
4 Answers
const isBrowser = () => typeof window !== "undefined"
isBrowser() && window.location.replace(res.data)

If you want to use window.location then you have to check first then use it isBrowser() && window.location.replace(res.data) instade of window.location.replace(res.data)

If you don't need to require any module based on the window availability, don't do it. In your case, you only need to make a redirection, not to importing any module.

Just:

authClick(e) {
        e.preventDefault();
        this.setState({ authorizing: true }, ()=> {
            axios.get(auth_url)
                .then((res) => {
                    this.setState({
                        authorizing: false
                    })

                     if (typeof window !== `undefined`){ 
                           window.location = res.data 
                     }
                }).catch((err) => {
                    console.log(err)
                })
        });
    }

Note the change of making a redirection with window.location but you can also use your window.location.replace if you want.

The link to the documentation is correct the window is not available during the build process so you must define a check.

The term module in the documentation would be replaced by the actual name of the module you are referencing. Then you would wrap the import/require with the window check as mentioned in the documentation.

For your purposes the code would look like this:

...

if (typeof window !== `undefined`){
  window.location.replace(res.data) // Window call
}

...

You would not need the require module since you are not importing a module.

Hope that clarifies.

Tip: put typeof window !== 'undefined' && window.whaterver-you-need to solve this.

Related