Tutorial

Images in Gatsby Using gatsby-image & gatsby-plugin-sharp

Published on July 30, 2019
Default avatar

By Juan Villela

Images in Gatsby Using gatsby-image & gatsby-plugin-sharp

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Ensuring that users get the best experience with images on the web can be a tedious task. However, with Gatsby, we can leverage the power of Sharp to get the best performance with a little setup and a rich toolset.

In this article, we’ll take a look at the gatsby-image component and how it can simplify the process of using images in various scenarios. The steps in this guide assume you have a working Gatsby project. So if you haven’t already, you can get started with Gatsby by following along the Gatsby First Steps article.

Getting Started

Let’s get started by installing the necessary plugins. Depending on the Gatsby starter you’re using, these might already be installed. Check the package.json to see if that’s the case.

Install

We’re installing a few things here. Each play a different role in our image setup. We’ll go into further detail in a bit.

$ npm install --save gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp

Configuration

Now we’ll add these to our gatsby-config.js.

gatsby-config.js
const path = require('path');

module.exports = {
  plugins: [
    ...
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'images',
        path: path.join(__dirname, `src`, `images`),
      },
    },
  ],
}

Notice that we are configuring gatsby-source-filesystem as well. This is to create file nodes from our images so they’re available through graphql queries. For this guide, we’re placing our images in the src/images directory.

As for our other plugins:

  • gatsby-plugin-sharp is a low-level helper that powers the connections between Sharp and gatsby-image. It also exposes several image processing functions.
  • gatsby-transformer-sharp facilitates the creation of multiples images of the right sizes and resolutions.

Working With Images

Now that we’re set up, we can start working with images in our site. Let’s create a hero.js component to use with our images.

src/components/hero.js
import React from 'react';

export default ({ data }) => (
  <section>
    <div>
      <h1>Hi, I like websites.</h1>
      <p>Sometimes I make them.</p>
    </div>
  </section>
)

Querying Images

The gatsby-transformer-sharp plugin creates nodes of type ImageSharp for us to query. They can be either fixed or fluid.

  • Fixed takes the width and heigh arguments in our queries and provides fixed-size images.
  • Fluid takes maxWidth and maxHeight as arguments in a query and provides responsive image sizes.

Both of these will have a number of varying file sizes that utilize the <picture> element to load the right file size based on media breakpoints.

src/components/hero.js
export const query = graphql`
  query {
    file(relativePath: { eq: "images/heroImage.jpg" }) {
      childImageSharp {
        fluid(maxWidth: 1600, maxHeight: 800) {
          ...GatsbyImageSharpFluid_withWebp
        }
      }
    }
  }
`

Our query includes the ...GatsbyImageSharpFluid_withWebp fragment, which essentially imports a few predetermined properties. You can read more about the available fragments in the gatsby-image Readme.

You can run this query in GraphiQL to browse the several useful properties at your disposal.

Using the Gatsby Image Component

Now that we have our query, let’s use it in the hero.js component we made earlier. We’ll need to import graphql from gatsby and Img from gatsby-image.

src/components/hero.js
import React from 'react';
import { graphql } from 'gatsby';
import Img from 'gatsby-image';

export default ({ data }) => (
  <section>
    <Img
      fluid={data.file.childImageSharp.fluid}
      alt="This is a picture of my face."
    />
    <div>
      <h1>Hi, I like websites.</h1>
      <p>Sometimes I make them.</p>
    </div>
  </section>
)

export const query = graphql`
  query {
    file(relativePath: { eq: "images/heroImage.jpg" }) {
      childImageSharp {
        fluid(maxWidth: 1600, maxHeight: 800) {
          ...GatsbyImageSharpFluid_withWebp
        }
      }
    }
  }
`

Aside from taking the alt prop, the Img component will also accept style and imgStyle as objects for adding custom styling to the parent container and img element, respectively. For a complete list, check out the component documentation.

Gatsby will render a responsive and lazy-loaded set of images. These will be compressed, have any unnecessary metadata stripped, and include a “blur-up” effect on load. Not bad!

Polyfill

There’s also a polyfill available for the object-fit/object-position CSS properties. You can instead import from gatsby-image/withIEPolyfill. The component will tell Gatsby to automatically apply the object-fit-images polyfill to your image.

src/components/hero.js
import React from 'react';
import { graphql } from 'gatsby';
import Img from 'gatsby-image/withIEPolyfill';

export default ({ data }) => (
  <section>
    <Img
      fluid={data.file.childImageSharp.fluid}
      objectFit="cover"
      objectPosition="50% 50%"
      alt="This is a picture of my face."
    />
    ...
  </section>
)

...

Image Compression

By default, gatsby-plugin-sharp uses various compression libraries. But there are a few options we can set if we’d like to modify the default behavior.

gatsby-config.js
module.exports = {
  plugins: [
    ...
    {
      resolve: 'gatsby-plugin-sharp',
      options: {
        useMozJpeg: false,
        stripMetadata: true,
        defaultQuality: 75,
      },
    },
  ],
}

We can optionally use MozJPEG for even better JPEG compression. However, keep in mind that this will likely significantly increase your build time.

Check out the plugin’s documentation for all the available methods to modify and optimize your images.

Conclusion

This is only scratching the surface of what you can do with images in Gatsby. Whether you’re looking to squeeze out as much performance as possible or create a quality experience for your users, Gatsby’s rich toolset has you covered. I encourage you to read all the linked resources and play around with the plugins to find what best suits your needs.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Juan Villela

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel