Migrating from v2 to v3
Looking for thev2 docs?
Have you run into something that’s not covered here?Add your changes to GitHub!
Introduction
This is a reference for upgrading your site from Gatsby v2 to Gatsby v3. Since the last major release was in September 2018, Gatsby v3 includes a couple of breaking changes. If you’re curious what’s new, head over to thev3.0 release notes.
If you want to start a new Gatsby v3 site, run
npm init gatsbyoryarn create gatsbyin your terminal.
Table of Contents
- Updating Your Dependencies
- Handling Breaking Changes
- Future Breaking Changes
- For Plugin Maintainers
- Known Issues
Updating Your Dependencies
First, you need to update your dependencies.
Update Gatsby version
You need to update yourpackage.json to use the latest version of Gatsby.
Or run
Please note: If you usenpm 7 you’ll want to use the--legacy-peer-deps option when following the instructions in this guide. For example, the above command would be:
Update Gatsby related packages
Update yourpackage.json to use the latest version of Gatsby related packages. You should upgrade any package name that starts withgatsby-*. Note, this only applies to plugins managed in thegatsbyjs/gatsby repository. If you’re using community plugins, they might not be upgraded yet. Many plugins won’t need updating so they may keep working (if not, please check their repository for the current status). You can run an npm script to see all outdated dependencies.
npm
Compare the “Wanted” and “Latest” versions and update their versions accordingly. For example, if you have this outdated version:
Install the new package with:
yarn
You’ll be given an overview of packages which to select to upgrade them tolatest.
Updating community plugins
Using community plugins, you might see warnings like these in your terminal:
If you are using npm 7, the warning may instead be an error:
This is because the plugin needs to update itspeerDependencies to include the new version of Gatsby (see sectionfor plugin maintainers). While this might indicate that the plugin has incompatibilities, in most cases they should continue to work. When using npm 7, you can pass the--legacy-peer-deps to ignore the warning and install anyway. Please look for already opened issues or PRs on the plugin’s repository to see the status. If you don’t see any, help the maintainers by opening an issue or PR yourself! :)
Handling dependencies for plugins that are not yet updated
Gatsby has anamazing ecosystem of plugins that make it easier to get up and running, and to incorporate various data sources and functionality into your Gatsby project. Part of that huge ecosystem includes dependency trees!
Depending on how the plugin authors have declared dependencies (e.g. marking a package as a dependency instead of a peerDependency) within those plugins, there could be a myriad of failures that arise. If you encounter any of these issues when migrating your project to Gatsby Version 3, we recommend that you useYarn resolutions within yourpackage.json.
Please note: If you rely on a plugin that is not found within thelist of plugins within the Gatsby framework, you very well may need to use the following resolutions in the near term.
The specific resolutions we recommend at this time are found below:
Handling version mismatches
When upgrading an already existing project (that has an existingnode_modules folder andpackage-lock.json file) you might run into version mismatches for your packages as npm/yarn don’t resolve to the latest/correct version. An example would be a version mismatch ofwebpack@4 andwebpack@5 that can throw an error like this:
An effective way to get around this issue is deletingnode_modules andpackage-lock.json and then runningnpm install again. Alternatively, you can usenpm dedupe.
Handling Breaking Changes
This section explains breaking changes that were made for Gatsby v3. Most, if not all, of those changes had a deprecation message in v2. In order to successfully update, you’ll need to resolve these changes.
Minimal Node.js version 12.13.0
We are dropping support for Node 10 as it is approaching maintenance EOL date (2021-04-30).The new required version of Node is12.13.0. See the main changes inNode 12 release notes.
CheckNode’s releases document for version statuses.
webpack upgraded from version 4 to version 5
We tried our best to mitigate as much of the breaking change as we could. Some are sadly inevitable. We suggest looking at theofficial webpack 5 blog post to get a comprehensive list of what changed.
If you hit any problems along the way, make sure the Gatsby plugin or webpack plugin supports version 5.
ESLint upgraded from version 6 to version 7
If you’re using Gatsby’s default ESLint rules (no customeslintrc file), you shouldn’t notice any issues. If you do have a custom ESLint config, make sure to read theESLint 6 to 7 migration guide
src/api is a reserved directory now
With therelease of Gatsby 3.7 we introducedFunctions. With this any JavaScript or TypeScript files insidesrc/api/* are mapped to function routes like files insrc/pages/* become pages. This also means that if you already have an existingsrc/api folder you’ll need to rename it to something else as it’s a reserved directory now.
Gatsby’sLink component
The APIspush,replace &navigateTo ingatsby-link (an internal package) were deprecated in v2 and now with v3 completely removed. Please usenavigate instead.
Removal of__experimentalThemes
The deprecated__experimentalThemes key insidegatsby-config.js was removed. You’ll need to define your Gatsby themes inside theplugins array instead.
Removal ofpathContext
The deprecated APIpathContext was removed. You need to rename instances of it topageContext. For example, if you passed information inside yourgatsby-node.js and accessed it in your page:
Removal ofboundActionCreators
The deprecated APIboundActionCreators was removed. Please rename its instances toactions to keep the same behavior. For example, in yourgatsby-node.js file:
Removal ofdeleteNodes
The deprecated APIdeleteNodes was removed. Please iterate over thenodes instead and calldeleteNode:
Removal offieldName &fieldValue fromcreateNodeField
The argumentsfieldName andfieldValue were removed from thecreateNodeField API. Please usename andvalue instead.
Removal ofhasNodeChanged from public API surface
This API is no longer necessary, as there is an internal check for whether or not a node has changed.
Removal ofsizes &resolutions for image queries
Thesizes andresolutions queries were deprecated in v2 in favor offluid andfixed.
Whilefluid,fixed, andgatsby-image will continue to work in v3, we highly recommend migrating to the newgatsby-plugin-image. Read theMigrating fromgatsby-image togatsby-plugin-image guide to learn more about its benefits and how to use it.
CallingtouchNode with the node id
CallingtouchNode with a string (the node id) was deprecated in Gatsby v2. Pass the fullnode totouchNode now.
CallingdeleteNode with the node id
CallingdeleteNode with a string (the node id) was deprecated in Gatsby v2. Pass the fullnode todeleteNode now.
Removal of threegatsby-browser APIs
A couple ofgatsby-browser APIs were removed. In the list below you can find the old APIs and their replacements:
getResourcesForPathnameSync=>loadPageSyncgetResourcesForPathname=>loadPagereplaceComponentRenderer=>wrapPageElement
Using a globalgraphql tag for queries
Until now you were able to use thegraphql tag for queries without explicitly importing it from Gatsby. You now have to import it:import { graphql } from 'gatsby'
CSS Modules are imported as ES Modules
The web moves forward and so do we. ES Modules allow us to better treeshake and generate smaller files. From now on you’ll need to import cssModules as:import { box } from './mystyles.module.css'
You can also import all styles using theimport * as styles syntax e.g.import * as styles from './mystyles.module.css'. However, this won’t allow webpack to treeshake your styles so we discourage you from using this syntax.
Migrating all your CSS could be painful or you’re relying on third-party packages that require you to use CommonJS. You can work around this issue for Sass, Less, Stylus & regular CSS modules using respective plugins. If you’re using regular CSS modules, please installgatsby-plugin-postcss to override the defaults.
This example covers Sass. The other plugins share the samecssLoaderOptions property.
File assets (fonts, pdfs, …) are imported as ES Modules
Assets are handled as ES Modules. Make sure to switch your require functions into imports.
If you’re usingrequire with expression orrequire.context (which is not recommended), you’ll have to append.default to your require statement to make it work.
webpack 5 node configuration changed (node.fs, node.path, …)
Some components need you to patch/disable node APIs in the browser, likepath orfs. webpack removed these automatic polyfills. You now have to manually set them in your configurations:
If it’s still not resolved, the error message should guide you on what else you need to add to your webpack config.
process is not defined
A common error isprocess is not defined. webpack 4 polyfilled process automatically in the browser, but with v5 it’s not the case anymore.
If you’re usingprocess.browser in your components, you should switch to a window is not undefined check.
If you’re using any other process properties, you want to polyfill process.
- Install
processlibrary -npm install process - Configure webpack to use the process polyfill.
GraphQL: character escape sequences inregex filter
In v2, backslashes inregex filters of GraphQL queries had to be escapedtwice, so/\w+/ needed to be written as"/\\\\w+/".
In v3, you only need to escape once:
GraphQL:__typename field is no longer added automatically
In v2, the__typename field used to be added implicitly when querying for a field of abstract type (interface or union).In v3,__typename has to be added explicitly in your query:
Schema Customization: Add explicitchildOf extension to types with disabled inference
Imagine you have node typeFoo that has several child nodes of typeBar (so you expect fieldFoo.childBar to exist).In Gatsby v2 this field was added automatically even if inference was disabled for typeFoo.
In Gatsby v3 you must declare a parent-child relationship explicitly for this case:
To make upgrading easier, check the CLI output of your site on the latest v2 and follow the suggestionswhen you see a warning like this:
If you don’t see any warnings, you are safe to upgrade to v3.
If this warning is displayed for a type defined by some plugin, open an issue in the plugin repowith a suggestion to upgrade (and a link to this guide).
You can still fix those warnings temporarily in your site’sgatsby-node.js file until it is fixed in the plugin.
Related docs:
Schema Customization: Extensions must be set explicitly
Starting with v3, whenever you define a field of complex type, you must also assignthe corresponding extension (or a custom resolver):
In Gatsby v2, we add those extensions for you automatically but display a deprecation warning.
To make upgrading easier, when you see a warning like the one below, check the CLI output of your site on the latest v2 and follow the suggestions provided.
If this warning is displayed for a type defined by some plugin, open an issue in the plugin repowith a suggestion to upgrade (and a link to this guide).
You can still fix those warnings temporarily in your site’sgatsby-node.js until it is fixed in the plugin.
If you don’t see any warnings, you are safe to upgrade to v3. Read more about custom extensions inthis blog post.
Schema Customization: RemovednoDefaultResolvers argument from inference directives
Search fornoDefaultResolvers entries and remove them:
Deprecation announcement fornoDefaultResolvers.
Schema Customization: Removemany argument fromchildOf directive
Themany argument is no longer needed for thechildOf directive in Gatsby v3:
Schema Customization: Consistent return fornodeModel.runQuery
For Gatsby v2,nodeModel.runQuery withfirstOnly: false returnsnull when nothing is found.In v3 it returns an empty array instead.
To upgrade, find all occurrences ofrunQuery (withfirstOnly: false or not set) and make sure checks for emptinessare correct:
Note: When using argumentfirstOnly: true the returned value isobject ornull.So do not confuse those two cases.
Future Breaking Changes
This section explains deprecations that were made for Gatsby v3. These old behaviors will be removed in v4, at which point they will no longer work. For now, you can still use the old behaviors in v3, but we recommend updating to the new signatures to make future updates easier.
touchNode
For Gatsby v2 thetouchNode API acceptednodeId as a named argument. This now has been deprecated in favor of passing the fullnode to the function.
In case you only have an ID at hand (e.g. getting it from cache or as__NODE), you can use thegetNode() API:
deleteNode
For Gatsby v2, thedeleteNode API acceptednode as a named argument. This now has been deprecated in favor of passing the fullnode to the function.
@nodeInterface
For Gatsby v2,@nodeInterface was the recommended way to implementqueryable interfaces.Now it is deprecated in favor of interface inheritance:
JSON imports: follow the JSON modules web spec
JSON modules are coming to the web. JSON modules only allow you to import the default export and no sub-properties. If you do import properties, you’ll get a warning along these lines:
webpack deprecation messages
When running community Gatsby plugins, you might see[DEP_WEBPACK] messages popup during the “Building JavaScript” or the “Building SSR bundle” phase. These often mean that the plugin is not compatible with webpack 5 yet. Contact the Gatsby plugin author or the webpack plugin author to flag this issue. Most of the time Gatsby will build fine, however there are cases that it won’t and the reasons why could be cryptic.
Usingfs in SSR
Gatsby v3 introduces incremental builds for HTML generation. For this feature to work correctly, Gatsby needs to track all inputs used to generate HTML file. Arbitrary code execution ingatsby-ssr.js files allow usage offs module, which is marked as unsafe and results in disabling of this feature. To migrate, you can useimport instead offs:
For Plugin Maintainers
In most cases, you won’t have to do anything to be v3 compatible. But one thing you can do to be certain your plugin won’t throw any warnings or errors is to set the proper peer dependencies.
gatsby should be included underpeerDependencies of your plugin and it should specify the proper versions of support.
If your plugin supports both versions:
Known Issues
This section is a work in progress and will be expanded when necessary. It’s a list of known issues you might run into while upgrading Gatsby to v3 and how to solve them.
reach-router
We vendoredreach-router to make it work for React 17. We added a webpack alias so that you can continue using it as usual. However, you might run into an error like this after upgrading:
To resolve the error above, make sure that you have updated all dependencies. It’s also possible that you have an outdated.cache folder around. Rungatsby clean to remove the outdated cache.
In some situations the webpack alias will be ignored, so you will need to add your own alias. The most common example is in Jest tests. For these, you should add the following to your Jest config:
Configuring using ajest.config.js file:
Configuring usingpackage.json:
webpack EACCES
You might see errors like these when using Windows or WSL:
Gatsby will continue to work. Please track theupstream issue to see how and when this will be fixed.
yarn workspaces
Workspaces and their hoisting of dependencies can cause you troubles if you incrementally want to update a package. For example, if you usegatsby-plugin-emotion in multiple packages but only update its version in one, you might end up with multiple versions inside your project. Runyarn why package-name (in this exampleyarn why gatsby-plugin-emotion) to check if different versions are installed.
We recommend updating all dependencies at once and re-checking it withyarn why package-name. You should only see one version found now.
Legacy Browser (IE 11 Polyfill)
If you plan on targeting IE 11, you might run into an error like this:
To fix this, first create a polyfill forObject.setPrototypeOf() in a file calledsetPrototypeOf.js at the root of the site:
Then create a file calledpolyfills.js, where you can add multiple polyfills (custom or imported):
Then inject them into webpack using theonCreateWebpackConfig API ingatsy-node.js during stagebuild-javascript:
IE11 browser will now use this polyfill forObject.setPrototypeOf().