Because Gatsby’s static build process ultimately generates a series of HTML files that maximize the speed at which Gatsby sites load in the browser, some issues can be difficult to diagnose. In many cases, issues surrounding static builds involve inaccessible globals or Webpack bundling issues. The Gatsby documentation outlines four specific cases that are common in Gatsby sites:
- Undefined browser globals. Because JavaScript can be executed on the server side or the client side, if your code references the
window
ordocument
object, those objects may be unavailable except when the Gatsby site is loaded in a browser. During the build process, you may run into errors such aswindow is not defined
, as it isundefined
before the site reaches the browser. There are two ways to handle this:- If your code requires the use of the
window
ordocument
object in the browser, perform a check to ensurewindow
ordocument
is defined so that the code within the check is executed only in the browser, as follows:if
(
typeof
window
!==
`undefined`
)
{
// Your window-reliant code here.
}
- If the offending code with references to the
window
ordocument
object is within therender
function of a React component, you’ll need to relocate that code into acomponentDidMount
lifecycle method in React or, if you’re using React hooks, into auseEffect
hook implementation to prevent its execution outside the browser.
- If your code requires the use of the
- Improperly exported pages. Because Gatsby automatically generates pages based on the contents of the pages directory, you must ensure that all files within that directory are exporting either a React component or a string. Otherwise, Gatsby’s automatic page generation will fail.
- Collision of
import
andrequire
in a single file. In Webpack 4, the bundler no longer permits the use of bothimport
andrequire
statements within the same file. Instead, Gatsby recommends using onlyimport
statements within Gatsby files, including gatsby-ssr.js and gatsby-browser.js. - Improper hydration. Gatsby allows for client-side functionality to proceed by hydrating rendered HTML with React. If this hydration doesn’t happen correctly, you will run into inconsistencies between the results of the
gatsby develop
andgatsby build
commands. If you discover inconsistencies between the build results, it’s likely that some logic in gatsby-ssr.js or gatsby-browser.js is causing a mismatch between the HTML generated by the server and that understood by the client.
AVOIDING ISSUES WITH THE WINDOW OBJECT
One edge case not enumerated in this list relates to NPM modules that are used as dependencies in Gatsby sites and refer to the window
object. Because these are upstream dependencies, if you report the issue and request a check on the window
object it may take some time before the maintainer responds. To avoid hacking into the module itself, which compromises dependency management, in gatsby-node.js you can customize your Webpack configuration such that during server-side rendering, the module is replaced with an empty dummy module:
// gatsby-node.js
exports
.
onCreateWebpackConfig
=
({
stage
,
loaders
,
actions
})
=>
{
if
(
stage
===
"build-html"
)
{
actions
.
setWebpackConfig
({
module
:
{
rules
:
[
{
test
:
/module-without-window-defined-check/
,
use
:
loaders
.
null
(),
},
],
},
})
}
}
An alternative to this approach is to use the loadable-components
package, which allows developers to use code splitting to force a module to dynamically load only in the browser and not during server-side rendering.
Leave a Reply