Updating to GatsbyV3

- by Colin on 10-3-2021
GatsbyV3 splash

copyright ©GatsbyJS – gatsbyjs.com

How I updated from GatsbyV2 to GatsbyV3. In this post, I explain some of the problems and pitfalls I had along the way and how I configured some of the new features provided.

It’s been a week since the new release was announced at Gatsby Conference 2021. If you haven’t updated yet, what are you waiting for!?

New Gatsby Cloud Features

There are various new features, including an updated integration with Gatsby Cloud, which now offers hosting from their CDN and incremental builds on the free tier. 😀 Brilliant reasons to get projects updated to GatsbyV3.

Create a new branch.

When updating a project’s dependencies, it is crucial to make sure that you’re using a tool like GitHub, so you can roll back your project if things go wrong.

// create a new branch
git checkout -b updating-gatsby-to-v3

// push the new branch up to out repo.
git push -u origin updating-gatsby-to-v3

Update to Gatsby V3

It’s always a good idea to read any migration documents provided. GatsbyJS provides a thorough overview of what’s new.

https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v2-to-v3/

npm install gatsby@latest || yarn upgrade-interactive --latest

When upgrading to V3, ensure that Gatsby and the core dependencies with the gatsby-prefix to their latest version. Look here for more information.

https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v2-to-v3/#update-gatsby-related-packages

Often when updating, other libraries may be flagged. For example, React may still be at version 16. It may be better to upgrade selectively in steps. For instance, update React & ReactDOM first, and then the Gatsby specific dependencies.

Once finished installing, it’s the moment of truth. Let’s run Gatsby Develop! Oh no, something has gone wrong. Let’s look at the error.

Webpack Error

In this case, the error alludes to Webpack, the build tool that conjures the Gatsby magic. Let’s clear the Gatsby Cache with Gatsby Clean and see if that helps.

Nope, hmph… As a last resort, it is always worth deleting the [node_modules] folder and reinstalling all the dependencies. Something may have gone wrong in the installation process. Fantastic, that has done the trick. The site builds without error. However, I see some warnings in my command-line interface. Upon navigating to localhost:8000, I notice that the site errors on the client.

CSS module warning

It seems to be an issue with the module.scss files. I should practice what I preach and read the migration documentation.

https://www.gatsbyjs.com/docs/reference/release-notes/migrating-from-v2-to-v3/#css-modules-are-imported-as-es-modules

If you are using css modules, then you now need to import them explicitly using the named JavaScript import syntax.

 
// better css tree shaking...
import { nameExports } from "./some.module.css"
// ...avoid this for more efficient css
import * from "./some.module.css"

Gatsby-Plugin-Image

The biggest new visual feature is a new gatsby-plugin-image.

https://www.gatsbyjs.com/plugins/gatsby-plugin-image/

It provides two new components. StaticImage && GatsbyImage. They share a similar API, but the use cases are a little different. If the image is dynamic and likely to be changed via a CMS, then GatsbyImage is the component to use. The link below explains the specifics.

https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/#restrictions-on-using-staticimage

The main difference between implementing V2 and V3 is that instead of using GraphQL fragments to configure the Sharp image processing, it now uses a GraphQL resolver function and Enums. Making it much simpler to configure.

https://www.gatsbyjs.com/docs/reference/release-notes/image-migration-guide/#graphql-changes

GraphiQL makes it easy to peruse, allowing users an overview of the many options available with the Sharp library.

New GraphiQL options

Too Square?

I’ll be the first to admit that this website isn’t stylish! Interestingly, nearly all of the images are square. I should confess that I never delved deeply into the image API in V2. Managing images was an afterthought, often with hacky-CSS. Having researched the new API for this post, I’ve realised that I misunderstood aspects of V2. As I come from a position of ignorance, you should probably take my opinions with a pinch of salt.

Previously…

Before this update, I usually configured images with a high max-width alongside the fluid setting, allowing for high resolution. This often meant small devices were downloading larger images than necessary. Though scrset may have alleviated this somewhat. Another problem was if the image wasn’t set with a large enough max-width, then it’d be stretched to fit its container.

Both of these situations degrade UX. The former increasing file-sizes and download times. Causing Google to dock points and affecting SEO. The latter causing undesirable artefacts, like pixelation, as the image stretches to fit the container. Many would consider these as acceptable or minor issues or perhaps too tricky or time-consuming to perfect. If this sounds familiar then keep reading on.

layout: CONSTRAINED

The new API solves the fixed / fluid issue by providing three layout settings. FULL_WIDTH, FIXED and CONSTRAINED. The link below shows each of these in action. (Scroll down a touch)

https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/#layout

The constrained option means the image will never stretch. Even if it doesn’t fill the container, but it will shrink. A very powerful feature, guaranteeing that the beautiful pictures on your site will never become stretched. 

Breakpoints

The API also allows for breakpoints, this ensures that images are never larger than the breakpoint. This makes targeting specific screen sizes and keeping Google happy super easy. The code below shows how simple it is to configure.


query ImageQuery {
  localFile {
    childImageSharp {
       gatsbyImageData(
         layout: CONSTRAINED,
         width: 1000
         placeholder: BLURRED,
         breakpoints: [667]
         formats: [AUTO, WEBP, AVIF]
    )}
  }
}

The code below shows how to hydrate the image data into the component using a getImage() helper function provided by the library.


import { GatsbyImage, getImage } from "gatsby-plugin-image"
<GatsbyImage 
  image={ getImage(data.localFile)} 
  alt="Picture of me"/ >

Problems Solved!👌

As I refactored this site, I began to realise how I’d neglected image optimisation. None of my images needs to be particularly large, and the layout implicitly forces them to be smallish. Yet, they were all using fluid with a large max-width. They’ve all been updated to the new CONSTRAINED setting. I made the design decision to limit the size of featured images on mobile devices, as opposed to having huge full width featured images. I think it looks much neater than before, especially on medium-sized screens.

What more could you ask for!?

The new gatsby-plugin-image provides easy to implement solutions straight out of the box! It’s simple to configure and elegantly couples styling, design and art-direction alongside optimisation, including for screen sizes.

Could it be any easier? Though I haven’t started experimenting, it will be extremely useful in combination with Flexbox and Grid layouts. Allowing for informed choices and enabling a variety of solutions depending on the situation.

I’ve barely scratched the surface of the new API and there are many other features. Like aspect ratio and AVIF support straight out the gate! I particularly like the simple config of the Sharp processing. You can check out more about Sharp processing at the links below.

https://sharp.pixelplumbing.com/

https://using-gatsby-image.gatsbyjs.org/traced-svg/

https://image-processing.gatsbyjs.org/

This article by Malte – @cramforce explains the advantages of AVIF very succinctly.

https://www.industrialempathy.com/posts/avif-webp-quality-settings/

I would highly recommend watching Laurie Barth’s demonstration at Gatsby Conf 2021. Thanks, Laurie – @laurieontech!

Time to update.

Now I have configured all the necessary images in my project to use the new plugin, it’s time to commit the changes.

git add .

git commit -m 'updated src to gatsby-plugin-image'

git push

Now I am ready to merge the updating-gatsby-to-v5 branch into the main production branch.

git checkout main

git merge updating-gatsby-to-v3

git commit -m 'updated to GatsbyV3 '

git push

Hooray, that’s the update complete. I’ve pushed my updates to Gatsby Cloud and it has started building, let’s hope there are no errors!

Typical Safari

A small aside, I noticed Safari wasn’t correctly styling my circular images (border-radius). Worked in FF and Chrome. I had to specifically target the <img> element nested inside of the <GatsbyImage/> component with the border-radius property. Strange, it was as if the overflow:hidden wasn’t working.

Lighthouse Improvements

I was hoping to include a comparison of this site’s lighthouse scores between GatsbyV3 the previous version. I’ve decided to write a whole new post on that subject. Update: see this new GatsbyJS Performance Audit

Incremental Builds

Of all the new features in GatsbyV3, I am particularly pleased to see incremental builds are now available on the free tier of Gatsby Cloud. When I first started using Gatsby Cloud in late 2020, I had a taster of incremental builds during the two-week trial and was very impressed. One of the few setbacks of static site generators is explaining to content managers the technical aspects concerning updates and rebuilds. Having to rebuild whole sites to change a spelling mistake does seem wasteful. Gatsby cacheing builds solves this problem, it makes the new integration plugins all the more enjoyable to use.

GatsbyV3 Conclusions

Managing images is now much easier and offers new solutions. Builds are faster and more efficient, especially if using Gatsby Cloud. This is better for both developers and content managers. No more long build times to change a spelling error! If hosting on Gatsby Cloud, then there is also the advantage of your site being hosted on their CDN (in collaboration with Fastly), meaning faster delivery for visitors. It’s all awe-inspiringly fast! I’m sure things can only get even better. Serverless functions are on the horizon.