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 #309

Closed
IstoraMandiri opened this issue Jun 2, 2016 · 38 comments
Closed

Window is not defined #309

IstoraMandiri opened this issue Jun 2, 2016 · 38 comments

Comments

@IstoraMandiri
Copy link
Contributor

@IstoraMandiri IstoraMandiri commented Jun 2, 2016

I'm trying to use a semantic-ui import along with my components.

Works fine in development but if I try to gatsby build, I get Error: ReferenceError: window is not defined.

I'm doing this:

import $ from 'jquery';
$.fn.transition = require('semantic-ui-transition');
$.fn.dropdown = require('semantic-ui-dropdown');

Is there any workaround?

Edit: Managed to get it working with:

try {
  $.fn.sidebar = require('semantic-ui-sidebar');
} catch (e) {
  console.log(e)
}
@KyleAMathews
Copy link
Contributor

@KyleAMathews KyleAMathews commented Jun 2, 2016

Yeah, during development, react components are only run in the browser where window is defined. When building, Gatsby renders these components on the server where window is not defined. Generally with React the solution to this is only access window in componentDidMount or to check that window exists before accessing it. For third party libraries that don't do this, what you've done looks great.

Loading

@AndersDJohnson
Copy link
Contributor

@AndersDJohnson AndersDJohnson commented Jun 17, 2016

@KyleAMathews I can't seem to get componentDidMount to fire in html.js or _template.jsx using gatsby develop, maybe it's not supposed to, or I'm doing something wrong?

Loading

@Maxhodges
Copy link

@Maxhodges Maxhodges commented Jul 6, 2016

@hitchcott can you share a bit more about your build? I just installed semantic-ui into a gatsby project but my CSS isn't working. Not sure how to get the CSS loaded in my page. React is suppose the in-line styles right, but how does it know about them? Also I suppose I should configure webpack to do the LESS build instead of gulp. Did you just install the webpack-lessloader?

Loading

@kylegach
Copy link
Contributor

@kylegach kylegach commented Jul 6, 2016

@Maxhodges — It’s Webpack, not React, that “knows” about your styles. Webpack knows because you import or require the compiled file(s) somewhere in the JS files that get bundled.

For example, I import my main styles.css in the _template.js file, so when Webpack builds the bundle, it includes those styles – inline when in development mode; external referenced file when in production (look at cssLink here for an example).

There’s no need for an additional LESS loader, as Gatsby already includes one in its default Webpack config.

Loading

@cybermill
Copy link

@cybermill cybermill commented Dec 23, 2016

for those of you that followed the directions on the Gatsby GitHub page for installing the docs-site...
import { colors } from 'utils/colors'
is the trouble maker and after commenting out this and ${colors.bg} the site developed nicely.

Loading

@Tseberechts
Copy link

@Tseberechts Tseberechts commented May 17, 2017

Would it be possible to show a better error message when this happens? I have no idea where to find the error.

Failed at generating HTML

/home/projects/snipsonian/node_modules/gatsby/dist/bin/cli.js:42
      throw err;
      ^
Error: ReferenceError: window is not defined
    at Object.defineProperty.value (render-page.js:44529:79)
    at __webpack_require__ (render-page.js:30:30)
    at Object.exports.__esModule (render-page.js:42560:24)
    at __webpack_require__ (render-page.js:30:30)
    at Object.defineProperty.value (render-page.js:42533:51)
    at __webpack_require__ (render-page.js:30:30)
    at Object.<anonymous> (render-page.js:80:19)
    at __webpack_require__ (render-page.js:30:30)
    at Object.assign.i (render-page.js:50:18)
    at render-page.js:53:10
error Command failed with exit code 1.

Loading

@KyleAMathews
Copy link
Contributor

@KyleAMathews KyleAMathews commented May 17, 2017

Loading

@Tseberechts
Copy link

@Tseberechts Tseberechts commented May 17, 2017

That worked! Thx.

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

Loading

@mohhasbias
Copy link

@mohhasbias mohhasbias commented Nov 19, 2017

the error is disappeared when using componetDidMount

Loading

@gregorskii
Copy link

@gregorskii gregorskii commented Nov 28, 2017

I have a similar issue, but I am using localStorage to persist some of my redux state on the browser. How do I bypass this issue if I cannot use window.localStorage in the store.js file?

😢

Thanks!

Loading

@heldrida
Copy link

@heldrida heldrida commented Nov 28, 2017

@gregorskii

const windowGlobal = typeof window !== 'undefined' && window

then, windowGlobal.localStorage

Loading

@gregorskii
Copy link

@gregorskii gregorskii commented Nov 28, 2017

Ya this worked, but I had to mock local storage using https://www.npmjs.com/package/localstorage-memory:

const windowGlobal = typeof window !== 'undefined' && window;
const localAdapter = windowGlobal ?
  adapter(windowGlobal.localStorage) :
  adapter(memoryStorage)
;

Using https://www.npmjs.com/package/redux-localstorage.

Loading

@CallMeLaNN
Copy link

@CallMeLaNN CallMeLaNN commented Mar 15, 2018

only access window in componentDidMount

Gist for third party js.

// index.js
import React from "react";
import Link from "gatsby-link";

// import "uikit/dist/js/uikit";
// Third party JS access `window` without
// `typeof window !== "undefined"` check

class Template extends React.Component {
  componentDidMount() {
    import("uikit/dist/js/uikit")
      .then((uikit) => {
        this.uikit = uikit;
      })
      .catch((error) => console.error(error));
  }
  render() {
    // ...
  }
}

// ...

Loading

@altcoder
Copy link

@altcoder altcoder commented May 7, 2018

@CallMeLaNN suggestion worked for me. With UIkit, I get:

WebpackError: Element is not defined

Putting the imports inside componentDidMount worked.

 componentDidMount() {
    try {
      this.UIkit = require("uikit/dist/js/uikit");
      this.Icons = require("uikit/dist/js/uikit-icons");
      this.UIkit.use(this.Icons);
    } catch (e) {
      console.error(e);
    }
  }

Loading

@joshwcomeau
Copy link
Contributor

@joshwcomeau joshwcomeau commented May 12, 2018

Yeah, during development, react components are only run in the browser where window is defined. When building, Gatsby renders these components on the server where window is not defined. Generally with React the solution to this is only access window in componentDidMount or to check that window exists before accessing it. For third party libraries that don't do this, what you've done looks great.

It would be super helpful to surface this early / prominently. I'm trying to build for the first time, and there are many issues I have to fix now, since I was unaware that this would become an issue. It's particularly stressful as I urgently need to deploy this; I'm submitting a proposal for something, and I need the site to be online.

I'm only looking to deploy to Github Pages (for now, at least), and so I don't need SSR. Is there a way to just build for clients?

Loading

@justintemps
Copy link

@justintemps justintemps commented Sep 20, 2018

It seems like with Gatsby v2, you need to choose between es6 and commonjs imports, you won’t be able to mix them up anymore for reasons having to do with webpack 4.

That being the case, and assuming you’re already using es6 imports, it would seem like @jfaeldon’s solution is the one to use here and @hitchcott’s won’t work anymore.

Can someone confirm that?

Loading

@hackhat
Copy link

@hackhat hackhat commented Oct 14, 2018

@joshwcomeau completely agree with you, also I don't think is a good idea to run dev in browser only and build in node.js. The difference is so big, and as in DEV and PROD environment you want to make the environments as similar as possible, I think gatsby should do the same, run both dev and build in an environment that is as similar as possible.

Loading

nbw added a commit to nbw/whentochat that referenced this issue Dec 3, 2018
Fixes a Gatsby build error where window is not available.

Refer to: gatsbyjs/gatsby#309
cbillowes added a commit to cbillowes/curious-programmer-oxygen that referenced this issue Dec 17, 2018
@lili21
Copy link

@lili21 lili21 commented Dec 19, 2018

so Can I make it run build in browser ? I don't need SSR.

Loading

@PHILATSHAKA
Copy link

@PHILATSHAKA PHILATSHAKA commented Jan 8, 2019

Hi,
I am experiencing the same issue here, Coverflow works fine for gatsby develop but for build it throws an error:
WebpackError: window is not defined

     - react-coverflow.js:1 Object.<anonymous>
       ~/react-coverflow/dist/react-coverflow.js:1:330
     
     - main.js:1 Object.<anonymous>
       ~/react-coverflow/main.js:1:1

import Coverflow from 'react-coverflow';
import { StyleRoot } from 'radium'

class Team extends React.Component {

render(){
return(

<Coverflow
displayQuantityOfSide={2}
navigation
infiniteScroll
enableHeading
active={0}
media={{
'@media (max-width: 720px)': {
width: '100%',
height: '200px'
},
'@media (min-width: 720px)': {
width: '100%',
height: '400px',
}
}}
>
Chairperson
Deputy Chairperson
General Secretary
Recording Secretary
Treasury
Marketing

  </Coverflow>
</StyleRoot>
)

}
}

export default Team;

Loading

@leonardolouie
Copy link

@leonardolouie leonardolouie commented Jun 20, 2019

I am using netlify for my server side

Loading

@gregorskii
Copy link

@gregorskii gregorskii commented Jun 20, 2019

If you are certain you are not using window a package likely is.

You have to define an empty window in webpack.

It’s not super straight forward, but this will lead you in the right direction:

https://stackoverflow.com/questions/37656592/define-global-variable-with-webpack

Loading

@agjs
Copy link

@agjs agjs commented Jun 24, 2019

I'm not really sure why is this issue closed? This issue, in fact, is probably the most critical one when Gatsby is concerned and the entire philosophy of it should be changed and fixed.

It's really bad that browser and SSR logic are coupled. Not to mention the fact that you run one version of the code in development and divergence of it in production. This is really bad. Why would you make such builds? The only difference between those two should be enabled debugging functionalities in development and e.g. source maps or whatever. This really makes it difficult and engaging to use Gatsby.

In my opinion, you should reopen this and prioritize this issue. This issue makes people literally give up on thousands of modules out there that depend on window and not all of them can be imported in componentDidMount e.g. HOC like modules etc.

Loading

@gregorskii
Copy link

@gregorskii gregorskii commented Jun 24, 2019

While I don’t disagree this is a pain point. One could argue those libraries written with logic around the window variable are not suited for SSR use. Those libraries themselves should check if window is defined and work in SSR mode.

No other comments to the deeper point you are making, that’s a philosophical discussion better suited to the maintainers.

Loading

@agjs
Copy link

@agjs agjs commented Jun 24, 2019

With all due respect, what you wrote makes no sense. Why would someone who is building a "browser-only" library check if window object exists? Can you name or point to a single library on the entire NPM registry that does this? Or you are saying that all those libraries that people wrote are written wrongly?

Or people should consider that there is a framework called "Gatsby" that needs this? One should be able to use Gatsby on one or another end and those ends should be ENTIRELY decoupled. This is the only point, really. Nothing philosophical about it.

Loading

@gregorskii
Copy link

@gregorskii gregorskii commented Jun 24, 2019

By design Gatsby is a static site generator. Most of the work it does to accomplish that is done outside of the browser at compile time. It’s not only a “client” or “browser” tool.

Server side rendering is by definition done on the “server” side, where “window” is not a thing.

Gatsby’s compiling is done with Webpack, webpack by default does not wire up a window variable. From my experience there is not only one way to adapt client libraries to work under webpack. This leads to the Gatsby config itself not capable of providing a simple one shot solution to fix all libraries that depend on “window”.

FWIW I think it makes sense to separate the part so of the tool to discuss which part of it is impeding what you wish to do.

Loading

jonpepler added a commit to jonpepler/asteroids-ml that referenced this issue Mar 21, 2020
begoat pushed a commit to begoat/udfast-ui that referenced this issue Mar 23, 2020
@rein96
Copy link

@rein96 rein96 commented Aug 7, 2020

image

Loading

@DanielRuf DanielRuf changed the title Window is not defiend Window is not defined Aug 7, 2020
Borghese-Gladiator added a commit to Borghese-Gladiator/Cool-Components that referenced this issue Jan 21, 2021
ShariqAli-Dev added a commit to scoloopmedia/web that referenced this issue Sep 4, 2021
Firebase would save the user into a local storage. As a result, if they
closed the tab or change the page, they would not be logged out.
However, this did not work for the username.

Change:
 - setUsername changes the username key in local storage and then
 changes toe username state to that change.
 - Logging out sets the username to null in local stroage.
 - Logging out redirects to the home page

Notes:
 - When you build, localStorage isn't defined because it's a browse-only
 feature. So you need to defined the window object and use it from there
gatsbyjs/gatsby#309 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet