gatsby: Window is not defined
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)
}
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 40
- Comments: 38 (8 by maintainers)
Commits related to this issue
- :bug: fix bug: window is not defined https://github.com/gatsbyjs/gatsby/issues/309 — committed to mildronize/my-site-v3-gatsby by mildronize 6 years ago
- Check window.location in componentDidMount Fixes a Gatsby build error where window is not available. Refer to: https://github.com/gatsbyjs/gatsby/issues/309 — committed to nbw/whentochat by nbw 6 years ago
- Check if window object exists on MenuBar component https://github.com/gatsbyjs/gatsby/issues/309 — committed to cbillowes/curious-programmer-oxygen by cbillowes 6 years ago
- https://github.com/gatsbyjs/gatsby/issues/309 — committed to latviancoder/staleclosures.dev by latviancoder 5 years ago
- https://github.com/gatsbyjs/gatsby/issues/309 — committed to latviancoder/staleclosures.dev by latviancoder 5 years ago
- https://github.com/gatsbyjs/gatsby/issues/309 — committed to latviancoder/staleclosures.dev by latviancoder 5 years ago
- fix: 🐛 Guard the use of window object during Gatsby build Used advice in this issue: https://github.com/gatsbyjs/gatsby/issues/309 — committed to jonpepler/asteroids-ml by jonpepler 4 years ago
- fix ParticleSmoke component for `npm run build` to succeed see: https://github.com/gatsbyjs/gatsby/issues/309#issuecomment-302043875 — committed to Borghese-Gladiator/Cool-Components by Borghese-Gladiator 3 years ago
- Attempt to fix build - https://github.com/gatsbyjs/gatsby/issues/309#issuecomment-302043875 — committed to mikerogers123/blog by deleted user 2 years ago
- Attempt #2 to fix build - https://github.com/gatsbyjs/gatsby/issues/309#issuecomment-302043875 — committed to mikerogers123/blog by deleted user 2 years ago
- Attempt #3 to fix build - https://github.com/gatsbyjs/gatsby/issues/309#issuecomment-302043875 — committed to mikerogers123/blog by deleted user 2 years ago
That worked! Thx.
Tip: put
typeof window !== 'undefined' && window.whaterver-you-need
to solve this.Yeah, during development, react components are only run in the browser where
window
is defined. When building, Gatsby renders these components on the server wherewindow
is not defined. Generally with React the solution to this is only accesswindow
incomponentDidMount
or to check thatwindow
exists before accessing it. For third party libraries that don’t do this, what you’ve done looks great.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.
@gregorskii
const windowGlobal = typeof window !== 'undefined' && window
then,
windowGlobal.localStorage
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?
@CallMeLaNN suggestion worked for me. With UIkit, I get:
Putting the imports inside componentDidMount worked.
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.
so Can I make it run build in browser ? I don’t need SSR.
Ya this worked, but I had to mock local storage using https://www.npmjs.com/package/localstorage-memory:
Using https://www.npmjs.com/package/redux-localstorage.
@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.
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.
the error is disappeared when using
componetDidMount
Gist for third party js.
@KyleAMathews I can’t seem to get
componentDidMount
to fire inhtml.js
or_template.jsx
usinggatsby develop
, maybe it’s not supposed to, or I’m doing something wrong?@wmlutz something like the below code block.
react
is loaded after the initial static bundle is received. So by the time the user reaches_handleSubmit
window
will exist.Please note if
react toasts
callswindow
onimport
then you might still experience the error.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?