An Introduction to Gatsby Plugin Image

Last Updated:
Gatsby Plugin Image Banner - Introduction to Gatsby Image

With the release of Gatsby v3.0 back in March 2021 the old Gatsby Image plugin was been replaced with Gatsby Plugin Image (gatsby-plugin-image). Gatsby Plugin Image introduces a brand new way of handling and transforming images within Gatsby.

It introduces a cleaner way of using GraphQL queries as well as a brand new StaticImage component. Throw in a couple of helper functions and a nicer API, this set of components seems to be a great improvement!

Table of Contents

The Old (Original) Gatsby Image Component

Gatsby Image is (was) a clever piece of code that works with the Gatsby GraphQL queries to easily generate optimized images. Under the hood it used Gatsby Plugin Sharp to handle its image transformations. It was initially a great solution to the problem of having heavy images slowing down a website. No need to mess about with custom lazy load packages, just drop in the component.

As the pressure for better, faster, and more efficient websites has increased, Gatsby have introduced a set of new and improved components, housed under the name Gatsby Plugin Image.

The Difference between Gatsby Image and Gatsby Plugin Image

Firstly it is worth looking at the differences between gatsby-image vs gatsby-plugin-image. The newer Gatsby Plugin Image has taken the older Gatsby Image, completely refactored it and introduced some great new features. These differences include:

Named Import

We have been used to GatsbyImage being a default export, we could import it directly from the package. This has all changed due to the introduction of several other features. Now GatsbyImage is a named import.

import { GatsbyImage } from "gatsby-plugin-image"

Not a gigantic change, but definitely something to remember when refactoring older components.

Static Image Component

How to use the Static Image Component

The reason for the change in the way we import the GatsbyImage component seems to be partly due to this new addition. The StaticImage component.

It provides a clean way of importing a static image. This is particularly useful if the image required is never going to change on a particular template or within a component. An example of this could be an image on a 404 page, or the site logo. In the past all images, whether dynamic or static used the same component.

The benefit of this new StaticImage component is that it uses absolute and relative  paths, rather than having to use gatsby-source-filesystem to find a local image. This is far better developer experience!

There are restrictions on how this component can be used, for example the name of the file must be provided directly inside the component that the StaticImage component is used in. This is due to it being analysed on build, so unable to use props. However, this should not be seen as an issue as dynamic images can still be used with the GatsbyImage component.

Change in Gatsby Image

There are a number of changes to the GatsbyImage component that you should probably be aware of before upgrading.

Gatsby Image has been updated to be a functional component. This means that it cannot be extended in the same way that could have been when it was a class based component. Now if you are wanting to reuse code across components, you should use Composition.

The ‘fluid’ image object no longer exists, and the data object created by the GraphQL query should not be altered as it could have been in the past.  When using the getImage function (expanded on below) the data returned should not be changed. This data is no longer seen as ‘public’, and the developers state that this could be changed without notice. Initially I thought that this meant the possibility for art directing images had been removed, but this is not the case. In fact this has now been made far simpler with the new withArtDirection function.

No More Fragments, New API

We do not need to type ...GatsbyImageSharpFixed any more. This has since been replaced with the GatsbyDataImage function. This function can take a range of arguments outlined in the gatsby-plugin-image documentation.

In essence it is a far cleaner way to getting the same result, with a few new additions.

As well as the ability to use blur up base4 images, and SVG traced loaders, there is now a Dominant Colour setting. This calculates the dominate colour of the image and uses it as a solid background colour whilst the image is loading.

There is also a new image format: AVIF. Originally used in video, this royalty free format is currently supported in Chrome, soon to be added to Android and Firefox. This new file format is usually half the size (weight) of a WebP format. This is going to be a great help in creating faster websites!

To read more about AVIF take a look at this article.

Introduction of new Helper Functions

There are four new additions to how images are managed with the Gatsby Plugin Image. They are a huge improvement over the original Gatsby Image plugin, and a real benefit to the developer experience.

Gatsby Image getImage()

The getImage function is an helper function used to make the code cleaner and easier to read. It accepts a ‘File’ that has been created in the GraphQL query, and returns an object to be passed into the Gatsby Image component. Gone are the days of having to comb through levels of nested objects to get to the ‘Fluid’ object.

Example of how to use GatsbyImage getImage

Gatsby Image getSrc()

I can see myself using this new helper function in a fair few places! It is used to return a particular images src URL. An example of how it could be used, would be providing absolute URLs to an SEO component. This was something I really struggled with when first getting to grips with Gatsby.

How to use Gatsby Image getSrc

Gatsby Image getSrcSet()

Much like the getSrc function, this function returns the supplied Files srcSet. As this is the fallback for the image it will most generally be a JPG or PNG.

How to use Gatsby Image getSrcSet

Gatsby Image withArtDirection()

In the past, to art direct an image we would have had to mess with the image object provided by GraphQL. Not a complete nightmare, but not a particularly ‘easy path’. This new functions is used alongside the GatsbyImage component to create unique media query based images in a much smoother fashion.

How to use Gatsby Image withArtDirection()

Considerations

Edit: This section was written on the release of the new gatsby-plugin-image and these points are no longer really relevant. However you may come across them if migrating an old Gatsby site to the newer APIs and components.

Before jumping in and using this new plugin/set of components on your site, there are few things to consider:

Using the Old with the New

Although Gatsby Image Plugin has been released as v1.0.0 and is ready to be used on production sites, other third parties may not have had a chance to update their dependencies. An example of this could be that you are using a CMS that has not updated to the newer version of the API and is still using Gatsby Image.

This is not a massive issue, as both the older and new plugin can be used together on a site. This may be something to consider though as the JavaScript bundle size will be increased.

Changing APIs

Making an upgrade to a new API is never ‘free’. There is a certain amount of work needed to refactor pre-existing components. If your site (or numerous sites) have a lot of areas where custom image sizes are used, the cost vs benefit may need to be considered. If the amount of work to implement is small then you may not see a few changes as an issue. But this could add up across sites/image implementations.

Can Gatsby Image be used with SVGs/GIFs?

Unfortunately Gatsby Image cannot be used to display SVG or GIF images.

Why will SVGS not work with Gatsby Image?

SVGs are vector files and can scale infinitely without loss of quality. There is no need to make multiple versions of the file for different sizes. To use an SVG it can be imported and used like so:

import yourSvgImage from './your_image.svg'

const App = () => <div><img src={yourSvgImage} /></div>

Why will GIFs not work with Gatsby Image?

The above is similar for how GIFs should be used. Although they are not vectors, Gatsby Image is not able to process the file type (although there have been talks about how it could be handled here).

Example of How to Use StaticImage

The Gatsby team have done a great job in making an easy to use component. To add an image using StaticImage do the following:

import { StaticImage } from "gatsby-plugin-image"
export function YourWrapperComponent() {
  return <StaticImage src="../images/yourStaticPicture.png" alt="Incredible Art" />
}

CodeSandBox demo of how to use a StaticImage component in Gatsby.

Example of How To Use Gatsby Image

The GatsbyImage component is similar to the older implementation, but with a few tweaks. For example, you still need to create the GraphQL query, but now we use the GatsbyImageData function alongside the getImage helper function. Then this is passed into the GatsbyImage component:

import { graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"

function BlogPost({ data }) {
  const image = getImage(data.blogPost.avatar)
  return (
    <section>
      <h2>{data.blogPost.title}</h2>
      <GatsbyImage image={image} alt={data.blogPost.author} />
      <p>{data.blogPost.body}</p>
    </section>
  )
}
export const postQuery = graphql`
  query {
    blogPost(id: { eq: $BlogId }) {
      title
      body
      author
      avatar {
        childImageSharp {
          gatsbyImageData(
            width: 400
            placeholder: BLURRED
            formats: [AUTO, WEBP, AVIF]
          )
        }
      }
    }
  }
`

CodeSandBox demo of how to use a GatsbyImage component in Gatsby.

[support-block]

Example of How To Use getSrc()

Much like the StaticImage component, this helper function is very easy to use. In this example the GraphQL query has been carried out in a parent component. The file has then been passed through as a prop and passed into the getSrc function. This function then returns the image src URL.

If the getSrc function doesn’t find an an image to return it will return undefined. This is because the helper function uses optional chaining to check the object.

import { getSrc } from "gatsby-plugin-image"
import SEO from "../SEO"

const YourWebPage = ({ data }) => {
  const seoImagePath = getSrc(data.file)
  return (
    <>
      <SEO imageSrc={seoImagePath} />
    </>
  )
}

CodeSandBox demo of how to use a getSrc helper function in Gatsby.

Example of How to use Gatsby Image getSrcSet()

Almost exactly the same as getSrc, this getSrcSet helper function has one small job. In this example the query has been carried out in its parent component and the File passed down. This could be handy for passing images to sliders or other components unable to use the GatsbyImage component.

If the getSrcSet function doesn’t find an an image srcSet to return it will return undefined. This is because the helper function uses optional chaining to check the object.

import { getSrcSet } from "gatsby-plugin-image"
import { MyCustomComponent } from "../"

const YourWebPage = ({ data }) => {
  const exposedImageSrcSet = getSrcSet(data.file)
  return (
    <>
      <MyCustomComponent imageSrcSet={exposedImageSrcSet} />
    </>
  )
}

CodeSandBox demo of how to use a getSrcSet helper function in Gatsby.

Example of How to use Gatsby Image withArtDirection()

There are a couple of steps needed to art direct images using GatsbyImage with the helper function withArtDirection.

Firstly multiple images are needed to be created in a the GraphQL query. This is because the component will be showing different images at different screen sizes. Once these images are created, they are passed into GatsbyImage via the withArtDirection function. In the example below a GraphQL query has already been run, and has passed through two images.

The withArtDirection function is set up by first passing in the default image, and then an array of media queries for any further images.

import { GatsbyImage, getImage, withArtDirection } from "gatsby-plugin-image"

export function MyArtDirectedImage({ defaultImage, smallerDirectedImage }) {
  const images = withArtDirection(getImage(defaultImage), [
    {
      media: "(max-width: 800px)",
      image: getImage(smallerDirectedImage),
    },
  ])
  return <GatsbyImage image={images} />
}

CodeSandBox demo of how to use a withArtDirection helper function in Gatsby.

Your Thoughts

This new set of components look like they are going to be a great addition to Gatsby’s already solid collection. Although early days, they have some real potential.

I would love to know your thoughts on the above, and if you have had any successes/issues with the components. Please let me know at @robertmars

Related Posts

Helpful Bits Straight Into Your Inbox

Subscribe to the newsletter for insights and helpful pieces on React, Gatsby, Next JS, Headless WordPress, and Jest testing.