Reputation: 9790
I am using Gatsby and importing jquery
.
When I run Gatsby build
I get the following error:
WebpackError: jQuery requires a window with a document.
This is due to Gatsby doing server side rendering.
I have read through a number of issues on GitHub (this one being the best one I could find).
My code looks like the following:
import React, { Component } from 'react'
import Link from 'gatsby-link'
import LandingScreen from '../components/LandingScreen'
import $ from 'jquery'
import 'fullpage.js/dist/jquery.fullPage.js'
import 'fullpage.js/dist/jquery.fullpage.css'
class TestPage extends Component {
componentDidMount() {
$('#fullpage').fullpage({
verticalCentered: false
});
}
render(){
return (
<main id="fullpage">
<LandingScreen />
</main>
)
}
}
export default TestPage
This is breaking so I tried the following based on the GitHub thread above, but this also fails:
if (typeof window !== 'undefined') {
import $ from 'jquery'
}
Can anyone advise how to import jquery
?
Upvotes: 3
Views: 3147
Reputation: 14436
Peter, I recently reported this to jQuery maintainers, but they politely told me... well... to kick rocks. Would be good, if you could badger them about this a bit, too.
Currently jquery
absolutely requires window
object, so it won't work on Node.js as a dependency. (with one exception: if you don't need a global jquery object, but just a local instance in one module, you can manually initialise it with JSDom, but that's probably not your use case)
Your way around this whole problem is that you don't actually have to import jQuery
or its plugins on server side. So my approach was to create 2 separate entry point files - app.jsx
and server.jsx
- for client bundle and server-side bundle respectively and Layout.jsx
as a shared root component.
app.jsx
and server.jsx
are entry points for client-side bundle and server-side bundle respectively, while Layout.jsx
contains shared code with html.
I import jquery only in app.jsx
bundle, so on client side it is present. On server side it is never imported and not included in server bundle.
You can take a look at my blog's code, how I set up Webpack in it and how do server rendering.
Upvotes: 0
Reputation: 802
Gatsby's components will run on both Node (no window
object there) in order to produce static HTML and on the client's browser as React components. This is why you get this error.
The plugin you are trying to use needs to run only on the client because it needs the actual viewport dimensions to operate. Gatsby has a special API for this that you can use to run the plugin only on client side. A quick solution would be to load jQuery there and initialize your plugin on onClientEntry
.
I would also suggest you find a more lightweight plugin that does the same thing without the jQuery dependency. It's a pity to use jQuery in a React stack. Maybe somebody else can recommend one.
Upvotes: 3