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

When building I get WebpackError: ReferenceError: window is not defined #10749

Closed
ergunpp opened this issue Jan 1, 2019 · 7 comments
Closed
Labels
type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@ergunpp
Copy link

ergunpp commented Jan 1, 2019

I have finally finished a project that runs fine on development mode.
However when trying to build, I get

WebpackError: ReferenceError: window is not defined

I get the error at several locations as stated below:

`WebpackError: ReferenceError: window is not defined

  • index.js:14 new Navi
    lib/src/components/Navi/index.js:14:24

  • bootstrap:25 a.render
    lib/webpack/bootstrap:25:1

  • bootstrap:24 a.read
    lib/webpack/bootstrap:24:1

  • bootstrap:36 renderToString
    lib/webpack/bootstrap:36:1

  • static-entry.js:190 Object../.cache/static-entry.js.webpack_exports.default
    lib/.cache/static-entry.js:190:18

  • bootstrap:24 e
    lib/webpack/bootstrap:24:1

  • gatsby-browser-entry.js:1 Promise._resolveFromExecutor
    lib/.cache/gatsby-browser-entry.js:1:1

  • bootstrap:68 new Promise
    lib/webpack/bootstrap:68:1

  • bootstrap:5 tryCatcher
    lib/webpack/bootstrap:5:1

  • bootstrap:50 MappingPromiseArray._promiseFulfilled
    lib/webpack/bootstrap:50:1

  • api-runner-ssr.js:3 MappingPromiseArray.PromiseArray._iterate
    lib/.cache/api-runner-ssr.js:3:16

  • bootstrap:67 MappingPromiseArray.init
    lib/webpack/bootstrap:67:1
    `
    The main code I am using windows is in the Navi Component:

`import React, {Component} from 'react'
import { Link } from 'gatsby'
import "./style.scss"
import Icon from 'components/Icon'


 

class Navi extends React.Component {
  
        constructor(props) {
        super(props);
        this.state = {
          windowWidth: window.innerWidth,
          mobileNavVisible: false
        };
        }
        
  handleResize() {
  this.setState({windowWidth: window.innerWidth});
}

  componentDidMount() {
    window.addEventListener('resize', this.handleResize.bind(this));
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.handleResize.bind(this));
  } 

  navigationLinks(){
    const {location, title} =this.props
    return(
      <ul className=
      {this.state.mobileNavVisible ? "navbar-nav mr-auto mt-2 mt-md-0" :"navbar-nav bd-navbar-nav"}
      >
                  <li
                    className={
                      location.pathname === '/' ? 'nav-item active' : 'nav-item'
                    }
                  >
                    <Link to="/" className="nav-link">
                      Anasayfa
                    </Link>
                  </li>
                  <li
                    className={
                      location.pathname === '/kedi/'
                        ? 'nav-item active'
                        : 'nav-item'
                    }
                  >
                    <Link to="/kedi/" className="nav-link">
                      Kedi
                    </Link>
                    
                  </li>
                  <li
                    className={
                      location.pathname === '/kopek/'
                        ? 'nav-item active'
                        : 'nav-item'
                    }
                  >
                    <Link to="/kopek/" className="nav-link">
                      Köpek
                    </Link>
                    
                  </li>
                   <li
                    className={
                      location.pathname === '/contact/'
                        ? 'nav-item active'
                        : 'nav-item'
                    }
                  >
                    <Link to="/contact/" className="nav-link">
                      İletişim
                    </Link>
                    
                  </li>
                </ul>
      
      )
    
  }
  
  renderMobileNav() {
      if(this.state.mobileNavVisible) {
        return this.navigationLinks();
      }
    }
    
  handleNavClick() {
      if(!this.state.mobileNavVisible) {
        this.setState({mobileNavVisible: true});
      } else {
        this.setState({mobileNavVisible: false});
      }
    }
    
  renderNavigation() {
      if(this.state.windowWidth <= 1080) {
        return [
           <nav className="navbar navbar-expand-sm navbar-light flex-md-row white-bg sticky-top bg-light">
              <div className="container">
                  <div className="navbar-header">
                    <Link className="navbar-brand" to="/">
                      <img src="/img/main-logo-2.png" style={{height:"50px"}} className="align-center" alt="Bestpet Logo" />
                    </Link>
                  
                   <button className="navbar-toggle menu-button" onClick={this.handleNavClick.bind(this)}><span className="menu-icon"><Icon name="bars" prefix="fas"></Icon></span></button>
                  
                  </div>
                <div className="navbar navbar-collapse">
                     {this.renderMobileNav()}
                </div>
              </div>
          </nav>
        ];
      } else {
        return [
          <nav className="navbar navbar-expand navbar-light flex-column flex-md-row white-bg sticky-top navbar-expand-md bg-light">
            <div className="container">
                <div className="navbar-header">
                    <Link className="navbar-brand" to="/">
                      <img src="/img/main-logo-2.png" style={{height:"50px"}} className="align-center" alt="Bestpet Logo" />
                    </Link>
            
                 </div>
                  <div className="navbar-nav-scroll ml-auto">
                    
                       {this.navigationLinks()}
                    
                  </div>
            </div>
          </nav>
        ]; 
      }
    }
  
  
  render() {
  return(
   
              this.renderNavigation()
         
  )
}
}

export default Navi

`

I seems that I need to change the complete structure of bootstrap media queries along with the code above. Is there an easy and quick way to do this?

How should the code be changed?

Appreciate your help, thanks a lot.

@sidharthachatterjee sidharthachatterjee added the type: question or discussion Issue discussing or asking a question about Gatsby label Jan 1, 2019
@sidharthachatterjee
Copy link
Contributor

sidharthachatterjee commented Jan 1, 2019

Happy new year @ergunpp

Apologies that you’re seeing this. The build is breaking because window (and other browser only APIs) aren’t available in Node and server side rendering is failing.

This works during develop because we do SSR only in build at the moment (something we’re working on changing to avoid confusion in the future)

The simple fix for this is to only access window in componentDidMount (since that only runs in the browser)

@sidharthachatterjee
Copy link
Contributor

In context of the example above, change

constructor(props) {
        super(props);
        this.state = {
          windowWidth: window.innerWidth,
          mobileNavVisible: false
        };
        }

to

constructor(props) {
        super(props);
        this.state = {
          windowWidth: null,
          mobileNavVisible: false
        };
        }

(you're already setting it in componentDidMount so this should just work)

@ergunpp
Copy link
Author

ergunpp commented Jan 1, 2019

Thank you.
It builds fine now. The only problem is that on first load the hamburger menu icon is displayed even on wider screens.

@sidharthachatterjee
Copy link
Contributor

Ah, right. So with server side rendering, you’ll have to default to one of the cases. Or you could use CSS media queries to set visibility based on viewport.

@sidharthachatterjee
Copy link
Contributor

Closing this for now but please feel free to reopen if there’s anything else @ergunpp

@ergunpp
Copy link
Author

ergunpp commented Jan 2, 2019

Is it possible to make a media query in the constructor and then define the default?

@sidharthachatterjee
Copy link
Contributor

@ergunpp Unfortunately that won't work because the constructor code is run during build (server side rendering) and since that is running in a non browser environment, there is no way we can access a media query

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

2 participants