Skip to content

Using dynamic image in gatsby-plugin-image

It can be time-consuming to ensure that users have an excellent experience with images on the web.

With Gatsby, we can take advantage of the capabilities of gatsby-plugin-image to achieve the best performance with little setup and a complete toolkit. Gatsby Image plugin handles the challenging aspects of creating images in various sizes and formats.

This article will teach us how to dynamically access local images in Gatsby applications by using the GatsbyImage component of the gatsby-plugin-image module and GraphQL. GatsbyImage differing from StaticImage (in the same gatsby-plugin-image module) is used when the image source is variable or computed.

We completed this project in a Codesandbox. To get started quickly, fork the Codesandbox or run the project.

GitHub Repository:

https://github.com/Olanetsoft/dynamic-image-with-gatsby-plugin-image

The following are required to complete this post for a better understanding:

  • Knowledge of JavaScript and React.js
  • Knowledge of Gatsby.js is not required but preferred
  • Gatsby CLI should be installed globally. Learn how to install it here

Gatsby is an open-source static site generator (SSG). Gatsby uses efficient pre-configuration for rapid page loads, code splitting, server-side rendering, intelligent image loading, asset optimization, and data prefetching.

Gatsby uses webpack, GraphQL and React.js to build and render high-performance web apps. Gatsby can also be used to create progressive web apps that adhere to current web standards and are designed for speed and security.

To create a new project, use the gatsby new <project name> command to scaffold a new project.

This command creates a new Gatsby project for us.

To start our application, we run the following command.

    cd <project name>
    npm run devevelop
Code language: HTML, XML (xml)

Once the app is initialized, and the dependencies are installed, we will see a message with instructions for navigating to our site and running it locally.

Gatsby will start a hot-reloading development environment accessible by default at http://localhost:8000

In the previous step, we installed and started our application, and now we can use the GatsbyImage component in our Gatsby site like we would use an <img> element in HTML. gatsby-plugin-image ships with the default Gatsby starter we installed.

We download sample images to our computer and save it inside src/images in our project folder as shown below:

Gatsby - Dynamic Image

Next, to create a blank home page with a title, we update pages/index.js file with the following code snippet:

    import * as React from "react";
    import { GatsbyImage, getImage } from "gatsby-plugin-image";
    import { graphql } from "gatsby";
    
    // styles
    const pageStyles = {
      display: "flex",
      flexDirection: "column",
      alignItems: "center",
      justifyContent: "center",
    };
    
    // title
    const titleStyles = {
      fontSize: "2rem",
      fontWeight: "bold",
      marginBottom: "1rem",
    };
    
    // name
    const nameStyle = {
      fontSize: "1.5rem",
      fontWeight: "bold",
      marginBottom: "1rem",
    };
    
    // markup
    const IndexPage = (props) => {
      return (
        <div style={pageStyles}>
          <h1 style={titleStyles}>Using dynamic image in gatsby-plugin-image</h1>
         //...
        </div>
      );
    };
    
    export default IndexPage;
Code language: JavaScript (javascript)

We should have something similar to this below:

Gatsby - Dynamic Image

When we rebuild our application, the images we added locally are included in Gatsby’s data layer and we can retrieve them using Graphql. Subsequently, we will use the GatsbyImage component to dynamically render these images.

Using sharp, Gatsby creates a childImageSharp node in it’s Graphql data layer for all local image. We will query the image data from this node and depending on our data source, the actual file node structure may differ. In the page query of src/pages/index.js we have:

    query {
        photos: allFile(
          sort: { fields: base, order: ASC }
          filter: { extension: { regex: "/(jpeg)/" } }
        ) {
          edges {
            node {
              id
              base
              childImageSharp {
                gatsbyImageData(
                  width: 600
                )
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
Code language: CSS (css)

By providing arguments to the gatsbyImageData resolver, we can customize the image. When lazy loading, we can additionally adjust the size, layout, and placeholder type used.

    query {
        photos: allFile(
          sort: { fields: base, order: ASC }
          filter: { extension: { regex: "/(jpeg)/" } }
        ) {
          edges {
            node {
              id
              base
              childImageSharp {
                gatsbyImageData(
                  placeholder: DOMINANT_COLOR
                  height: 400
                  formats: AUTO
                  width: 600
                )
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
Code language: CSS (css)

Advanced image processing techniques are also available. The API documentation contains a complete list of options.

We will update src/pages/index.js with the following code snippet:

    import * as React from "react";
    import { GatsbyImage, getImage } from "gatsby-plugin-image";
    import { graphql } from "gatsby";
    
    //...
    
    // markup
    const IndexPage = (props) => {
      return (
        <div style={pageStyles}>
          <h1 style={titleStyles}>Using dynamic image in gatsby-plugin-image</h1>
          {props.data.photos.edges.map((img) => (
            <div key={img.node.id}>
              <GatsbyImage
                fluid={img.node.childImageSharp.fluid}
                alt={img.node.base.split("-").join(" ").split(".")[0]}
                image={getImage(img.node)}
              />
              <h2 style={nameStyle}>
                {img.node.base.charAt(0).toUpperCase() +
                  img.node.base.substr(1).split("-").join(" ").split(".")[0]}
              </h2>
            </div>
          ))}
        </div>
      );
    };
    
    export const pageQuery = graphql`
      query {
        photos: allFile(
          sort: { fields: base, order: ASC }
          filter: { extension: { regex: "/(jpeg)/" } }
        ) {
          edges {
            node {
              id
              base
              childImageSharp {
                gatsbyImageData(
                  placeholder: DOMINANT_COLOR
                  height: 400
                  formats: AUTO
                  width: 600
                )
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
    `;
    export default IndexPage;
Code language: JavaScript (javascript)

In the code snippet above,

  • To display the image on the page, we utilize the GatsbyImage component.
  • We used the getImage() function as an optional utility to make the code cleaner.
  • The GatsbyImage component accepts a File provided via getImage() and outputs file.childImageSharp.gatsbyImageData.

Testing our application we should have something similar to what is shown in the screenshot below:

https://www.loom.com/share/8ce45062f15c44ad9ae0f89d66bf0724

With our GatsbyImage instance, we can customize placeholders, formats, transformations, quality, height etc.

Let us update the page query in src/pages/index.js to the following:

    //...
    
    // markup
    const IndexPage = (props) => {
      return (
        <div style={pageStyles}>
         // ...
        </div>
      );
    };
    
    export const pageQuery = graphql`
      query {
        photos: allFile(
          sort: { fields: base, order: ASC }
          filter: { extension: { regex: "/(jpeg)/" } }
        ) {
          edges {
            node {
              id
              base
              childImageSharp {
                gatsbyImageData(
                  placeholder: BLURRED
                  height: 400
                  formats: AUTO
                  width: 600
                  quality: 70 # 50 by default
                  transformOptions: { grayscale: true }
                )
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
    `;
    export default IndexPage;
Code language: JavaScript (javascript)

The following is an example of what our application should look like:

Gatsby - Dynamic Image

https://www.loom.com/share/b1967767a22e4189bf5288b644dcca35

In this article, we learned how to use the GatsbyImage component of the gatsby-plugin-image module. We also learned how to apply optimizations and transformations to the rendered image.

  • Dynamic [GatsbyImage](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/#transformoptions) API Docs
  • Gatsby.js
Back to top

Featured Post