Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window is not defined at production build #5835

Closed
MaralS opened this issue Jun 11, 2018 · 18 comments
Closed

Window is not defined at production build #5835

MaralS opened this issue Jun 11, 2018 · 18 comments

Comments

@MaralS
Copy link

MaralS commented Jun 11, 2018

Description

I want to trigger window width to change the content of my website. But I don't know how to fix my issue.
Webpack error : window is not defined at production build

Expected result

Production build successful.

Actual result

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Helmet } from 'react-helmet'
import Link from 'gatsby-link'
import 'flexboxgrid/dist/flexboxgrid.min.css';
import { Footer, Header } from '../components/organisms'
import { Modal, Project } from '../components/molecules'

import '../scss/main.scss'

class Index extends Component {

  constructor(props) {
    super(props)
   this.state = {
    width: window.innerWidth,
    };
  }
  componentDidMount() {
    const width = typeof window !== 'undefined' && window
  }

  componentWillMount() {
    window.addEventListener('resize', this.handleWindowSizeChange);
  }

  // make sure to remove the listener
  // when the component is not mounted anymore
  componentWillUnmount() {
    window.removeEventListener('resize', this.handleWindowSizeChange);
  }

  handleWindowSizeChange = () => {
    this.setState({ width: window.innerWidth });
  };
  
  render(){
    const { width } = this.state;
    const isMobile = width <= 600;
    console.log(width, ' px')
    const {data} = this.props;

    return(
      <div className="wrapper">
      
        <div className="wrapper__top">
            <Helmet>
            <html lang="fr" />
            <meta charSet="utf-8" />
            <meta httpEquiv="X-UA-Compatible" content="IE-edge,chrome=1" />
            <meta name="viewport" content="width=device-width,initial-scale=1" />
            <link rel="icon" type="image/png" href="/favicon.png" />
          </Helmet>
          <Header />
          <main>
           {/* Affichage du Teaser pour les navigateurs qui ont une largeur supérieure ou égale à 600px */}
           {
             (isMobile && this.props.location.pathname === '/') ? 
             <div>
             {data.allProjectsJson.edges.map(({ node }, i) =>
                       (<Project
                           key={i}
                           title={node.title}
                           category={node.category}
                           image={{
                               src: node.image.childImageSharp.original.src,
                               alt: node.title,
                           }}
                          logo={{
                            src: node.logo.childImageSharp.original.src,
                            alt: node.title,
                          }}
                           website={node.website}
                       >
                           <p dangerouslySetInnerHTML={{ __html: node.description }} />
                       </Project>),
                   )}
              </div> 
             : this.props.children()
           }

          </main>
          <Footer />
        </div>
       
        
        
        
      </div >
    )
  }
}
Index.propTypes = {
  children: PropTypes.func.isRequired,
  location: PropTypes.shape({
    pathname: PropTypes.string,
  }).isRequired,
  data: PropTypes.object.isRequired
};
export default Index;
export const getSiteHeader = (siteTitle, description) =>
  (<Helmet>
    <title>{`${siteTitle} | Maral Sabbagh`}</title>
    <meta name="description" content={description} />
  </Helmet>);

  
//eslint-disable-next-line no-undef
export const pageQuery = graphql `
query LayoutQuery {

 allProjectsJson {
    edges {
      node {
        title
        category
        description
        image {
          childImageSharp {
            original {
              src
            }
          }
        }
        logo {
          childImageSharp {
            original {
              src
            }
          }
        }
        website
      }
    }
  }
   allGeneralJson(filter: {url: {eq: "/projets"}}){
    edges{
      node{
        url
        pageTitle
        metaDesc
        metaTitle
        

      }
    }
  }
}
`;


Environment

 gatsby info --clipboard
module.js:549
    throw err;
    ^

Error: Cannot find module 'regenerator-runtime/runtime'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (C:\Users\Maral Sabbagh\AppData\Roaming\npm\node_modules\gatsby-cli\lib\index.js:88:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)

Thanks for your help

@KyleAMathews
Copy link
Contributor

window isn't available when building a site — check out this page for some work arounds https://www.gatsbyjs.org/docs/debugging-html-builds/#how-to-check-if-code-classlanguage-textwindowcode-is-defined

@ryanditjia
Copy link
Contributor

constructor(props) {
    super(props)
   this.state = {
    width: window.innerWidth, // this line is the culprit
    };
  }

I strongly suggest you use react-media for this case.

But if you don’t want to, changing to this should fix it:

class Index extends Component {
  constructor(props) {
    super(props)
    this.state = {
      width: 0, // or your default width here
    }
  }
  componentDidMount() {
    this.handleWindowSizeChange() // Set width
    window.addEventListener('resize', this.handleWindowSizeChange)
  }

  componentWillMount() {
    // Don’t use this as the API is deprecated
  }

  // make sure to remove the listener
  // when the component is not mounted anymore
  componentWillUnmount() {
    window.removeEventListener('resize', this.handleWindowSizeChange)
  }

  handleWindowSizeChange = () => {
    this.setState({ width: window.innerWidth })
  }

  // rest of code
}

Also note that there will be small hit to performance, unless you debounce the resize eventListener. Let me know if you need more help!

@MaralS
Copy link
Author

MaralS commented Jun 11, 2018

@ryanditjia thanks I'll check, I didn't know that I had to set the inner width to 0. For this project I won't use this module but for the next It could be more simpler.
Thank you so much

It could be great if this issue could be be fixed in the next version of Gatsby @KyleAMathews

@ryanditjia
Copy link
Contributor

ryanditjia commented Jun 11, 2018

This isn’t issue with Gatsby. Just one of the gotchas of server-side rendering with React.

When Node tries to build, it instantiates the class, and in the constructor finds window, which is a browser global (Node doesn’t have window).

EDIT: it doesn’t have to be zero. Just as long as you don’t mention window it should be fine.

@MaralS
Copy link
Author

MaralS commented Jun 11, 2018

@ryanditjia thanks for the explanation :)
Everything works fine now :)

@daxaxelrod
Copy link

daxaxelrod commented Aug 29, 2018

I'm actually having a similar issue. I have this search page and I allow the user to press enter to fire off a redux action. When an action is dispatch, props changes forcing a rerender. When the user then goes to another page, i get window.removeEventListener is not defined. Here's my code.

error

constructor(props){
    super(props);
    this.enterToSearch = this.enterToSearch.bind(this);
    this.state = {
      searchTerm: ""
    }
  }

  enterToSearch = (event) => {
    if (event.keyCode == 13) { //enter key
      this.props.Actions.searchZA(this.state.searchTerm);
      this.setState({searchTerm: ""})
    }
  }


  componentDidMount(props){
    window.addEventListener("keydown", this.enterToSearch)
    if (this.props.ZA == []){
      this.setState({ZA: "Nothing here"});
    } else {
      this.setState({ZA: this.props.ZA});
    }
  }


  componentWillUnmount() {
    window.removeEventListner("keydown", this.enterToSearch)
  }

@jonniebigodes
Copy link

@daxaxelrod i had a similar issue with that a while ago while trying to get a resize event to work. a good workaround that did the trick for me was:

componentDidMount() {
    if (typeof window !== 'undefined') {
      window.addEventListener('resize', this.setChartDimensions)
    }
   ------
  }
  componentWillUnmount() {
    if (typeof window !== 'undefined') {
      window.removeEventListener('resize', this.setChartDimensions)
    }
  }

@jserrao
Copy link
Contributor

jserrao commented Sep 28, 2018

Anybody have a sense of how to fix this error for AudioContext()? The only way I've ever used it is mounting to the window object - is there another way to do this? I'm trying to use the react-media-player component. Same issue as others in this thread - works fine in dev mode working with the client but when you build out for SSR, I'm getting the window is not defined:

import React, { Component } from 'react'
import { Media, Player, controls } from 'react-media-player'
import PlayPause from './PlayPause'
import MuteUnmute from './MuteUnmute'

const { CurrentTime, SeekBar, Duration, Volume } = controls

const audioContext = new (window.AudioContext || window.webkitAudioContext)()
const panner = audioContext.createPanner()

panner.setPosition(0, 0, 1)
panner.panningModel = 'equalpower'
panner.connect(audioContext.destination)


class AudioPlayer extends Component {
  componentDidMount() {
    const source = audioContext.createMediaElementSource(this._player.instance)
    source.connect(panner)
    panner.connect(audioContext.destination)
  }

  _handlePannerChange = ({ target }) => {
    const x = +target.value
    const y = 0
    const z = 1 - Math.abs(x)
    panner.setPosition(x, y, z)
  }

  render() {
    return (
      <Media>
        <div>
          <Player
            ref={c => this._player = c}
            src={this.props.src}
            useAudioObject
          />
          <section className="media-controls">
            <div className="media-title-box">
              <PlayPause className="media-control media-control--play-pause"/>
              <div className="media-title-content">
                <div className="media-title">{ this.props.mediaTitle }</div>
                <div className="media-subtitle">{ this.props.mediaSubtitle }</div>
              </div>
            </div>
            <div className="media-controls-container">
              <CurrentTime className="media-control media-control--current-time"/>
              <SeekBar className="media-control media-control--volume-range"/>
              <Duration className="media-control media-control--duration"/>
            </div>
            <div className="media-sound-controls">
              <MuteUnmute className="media-control media-control--mute-unmute"/>
              <Volume className="media-control media-control--volume"/>
            </div>            
          </section>
        </div>
      </Media>
    )
  }
}

export default AudioPlayer

@antoinerousseau
Copy link
Contributor

@daxaxelrod you have a typo, that's why. removeEventListner => removeEventListener

@daxaxelrod
Copy link

@antoinerousseau wow I need to start using a linter. Thanks 😊

@maniart
Copy link

maniart commented Aug 26, 2019

Posting this here since I spent a good chunk of my Friday on this last week.

  • Periodically build your Gatsby site as you're developing it so you're aware of such issues as you're developing, not the day of the launch. Don't rely too much on the development experience. Build has its own gotchas (including this one) that you'd want to learn about early on.
  • 3rd party libraries that depend on window can be fixed as mentioned in the docs. You can include multiple window-dependent libraries in one go:
rules: [{
  test: /bad-module|another-one|and-a-third-one/,
  use: loaders.null(),
}]
  • Write a simple util function like so export const isBrowser = () => typeof window !== 'undefined' and then use it everywhere: import { isBrowser } from './utils'; {isBrowser() && <CodeThatNeedsWindow />}

@abhagsain
Copy link

I had this issue and I did this.


  const [hasRan, setHasRan] = useState(false)
  const [screenSize, setScreenSize] = useState({
    height: 0,
    width: 0,
  })
  const updateScreenSize = () => {
    setScreenSize({ width: window.innerWidth, height: window.innerHeight })
  }
  useEffect(() => {
    if (!hasRan) {
      setHasRan(true)
      updateScreenSize()
    }
    window.addEventListener("resize", updateScreenSize)
    return () => {
      window.removeEventListener("resize", updateScreenSize)
    }
  }, [screenSize])

It solved my issue 😁

@pmarxbraun
Copy link

Hello,

Got the same issue.
'gatsby build' throws me this

failed Building static HTML for pages - 9.517s

 ERROR #95312 

"window" is not available during server side rendering.

See our docs page for more info on this error: https://gatsby.dev/debug-html


  216 | 
  217 |   // Find the supported transform prop and style names.
> 218 |   var docElemStyle = window.document.documentElement.style;
      | ^
  219 |   var style = 'transform';
  220 |   var styleCap = 'Transform';
  221 |   var found = false;


  WebpackError: ReferenceError: window is not defined
  
  - muuri.js:218 
    node_modules/muuri/dist/muuri.js:218:1
  
  - muuri.js:19 
    node_modules/muuri/dist/muuri.js:19:63
  
  - muuri.js:22 Object../node_modules/muuri/dist/muuri.js
    node_modules/muuri/dist/muuri.js:22:2
  
  - index.js:1 Object../node_modules/muuri-react/build/index.js
    node_modules/muuri-react/build/index.js:1:1034
  
  - index.js:1 n
    node_modules/muuri-react/build/index.js:1:112
  
  - index.js:1 Module.<anonymous>
    node_modules/muuri-react/build/index.js:1:15762
  
  - index.js:1 n
    node_modules/muuri-react/build/index.js:1:112
  
  - index.js:1 ./node_modules/muuri-react/build/index.js
    node_modules/muuri-react/build/index.js:1:915
  

Any idea how to tackle this problem ?
Thanks !

@jonniebigodes
Copy link

@pmarxbraun it seems it's related to the muuri-react package, as that package is trying to write access the window api that is not acessible during the build process with Gatsby. You have options here, you can try and see if this helps with your case or try "offloading" the component where that package is used with loadable-components like mentioned here. Otherwise feel free to provide a minimal reproduction following these steps with that package and the code you're using so that it can be better looked at.

@beckzayi
Copy link

beckzayi commented Mar 23, 2020

@jonniebigodes Thanks for your advice. I finnaly used "@loadable/component" to fix the problem.

My scenario: try to use "swagger-ui-react" in Gatsby, but receive ReferenceError: window is not defined.

Firstly, I tried adding some code to gatsby-browser.js, but it didn't work as below:
import SwaggerUI from 'swagger-ui-react';
window.SwaggerUI = SwaggerUI;

Next, I tried your advice "load-component", and it worked for my case.
import Loadable from '@loadable/component';
const SwaggerUI = Loadable(() => import('swagger-ui-react'));
export default () => ( <SwaggerUI /> )

@jonniebigodes
Copy link

@beckzayi no need to thank, just glad that you managed to solve your issue aswell.

@technikhil314
Copy link

technikhil314 commented Apr 25, 2020

using globalThis works just fine. It wont work in old browsers though i.e nothing but i.e. :)
Can some one help me understand if it has any caveats?

@AjayDhimanELS
Copy link

AjayDhimanELS commented Jul 29, 2020

(navigate('/app/login'))}

this navigate function of gatsby is causing issues for me.
while running npm build it says:
window is not available during server side rendering. and :

var navigate = function navigate(to, options) { window.___navigate(rewriteLinkPath(to, window.location.pathname), options); }; exports.navigate = navigate;

(indicates at window)
Any possible solutions for me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests