Using dynamic image in gatsby-plugin-image

Idris Olubisi

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.

Sandbox

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

Prerequisite

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

Getting Started with Gatsby

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.

Creating a new project and Installing Dependencies

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.

1cd <project name>
2 npm run devevelop

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

Building our project

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:

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

1import * as React from "react";
2 import { GatsbyImage, getImage } from "gatsby-plugin-image";
3 import { graphql } from "gatsby";
4
5 // styles
6 const pageStyles = {
7 display: "flex",
8 flexDirection: "column",
9 alignItems: "center",
10 justifyContent: "center",
11 };
12
13 // title
14 const titleStyles = {
15 fontSize: "2rem",
16 fontWeight: "bold",
17 marginBottom: "1rem",
18 };
19
20 // name
21 const nameStyle = {
22 fontSize: "1.5rem",
23 fontWeight: "bold",
24 marginBottom: "1rem",
25 };
26
27 // markup
28 const IndexPage = (props) => {
29 return (
30 <div style={pageStyles}>
31 <h1 style={titleStyles}>Using dynamic image in gatsby-plugin-image</h1>
32 //...
33 </div>
34 );
35 };
36
37 export default IndexPage;

We should have something similar to this below:

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.

Adding images to our page query

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:

1query {
2 photos: allFile(
3 sort: { fields: base, order: ASC }
4 filter: { extension: { regex: "/(jpeg)/" } }
5 ) {
6 edges {
7 node {
8 id
9 base
10 childImageSharp {
11 gatsbyImageData(
12 width: 600
13 )
14 fluid {
15 ...GatsbyImageSharpFluid_withWebp
16 }
17 }
18 }
19 }
20 }
21 }

Configuring our Images

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.

1query {
2 photos: allFile(
3 sort: { fields: base, order: ASC }
4 filter: { extension: { regex: "/(jpeg)/" } }
5 ) {
6 edges {
7 node {
8 id
9 base
10 childImageSharp {
11 gatsbyImageData(
12 placeholder: DOMINANT_COLOR
13 height: 400
14 formats: AUTO
15 width: 600
16 )
17 fluid {
18 ...GatsbyImageSharpFluid_withWebp
19 }
20 }
21 }
22 }
23 }
24 }

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

Displaying our Images

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

1import * as React from "react";
2 import { GatsbyImage, getImage } from "gatsby-plugin-image";
3 import { graphql } from "gatsby";
4
5 //...
6
7 // markup
8 const IndexPage = (props) => {
9 return (
10 <div style={pageStyles}>
11 <h1 style={titleStyles}>Using dynamic image in gatsby-plugin-image</h1>
12 {props.data.photos.edges.map((img) => (
13 <div key={img.node.id}>
14 <GatsbyImage
15 fluid={img.node.childImageSharp.fluid}
16 alt={img.node.base.split("-").join(" ").split(".")[0]}
17 image={getImage(img.node)}
18 />
19 <h2 style={nameStyle}>
20 {img.node.base.charAt(0).toUpperCase() +
21 img.node.base.substr(1).split("-").join(" ").split(".")[0]}
22 </h2>
23 </div>
24 ))}
25 </div>
26 );
27 };
28
29 export const pageQuery = graphql`
30 query {
31 photos: allFile(
32 sort: { fields: base, order: ASC }
33 filter: { extension: { regex: "/(jpeg)/" } }
34 ) {
35 edges {
36 node {
37 id
38 base
39 childImageSharp {
40 gatsbyImageData(
41 placeholder: DOMINANT_COLOR
42 height: 400
43 formats: AUTO
44 width: 600
45 )
46 fluid {
47 ...GatsbyImageSharpFluid_withWebp
48 }
49 }
50 }
51 }
52 }
53 }
54 `;
55 export default IndexPage;

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

Customizing gatsbyImageData

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:

1//...
2
3 // markup
4 const IndexPage = (props) => {
5 return (
6 <div style={pageStyles}>
7 // ...
8 </div>
9 );
10 };
11
12 export const pageQuery = graphql`
13 query {
14 photos: allFile(
15 sort: { fields: base, order: ASC }
16 filter: { extension: { regex: "/(jpeg)/" } }
17 ) {
18 edges {
19 node {
20 id
21 base
22 childImageSharp {
23 gatsbyImageData(
24 placeholder: BLURRED
25 height: 400
26 formats: AUTO
27 width: 600
28 quality: 70 # 50 by default
29 transformOptions: { grayscale: true }
30 )
31 fluid {
32 ...GatsbyImageSharpFluid_withWebp
33 }
34 }
35 }
36 }
37 }
38 }
39 `;
40 export default IndexPage;

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

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

Conclusion

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.

Resources

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

Idris Olubisi

Software Engineer & Technical Writer

A Software Engineer & Technical Writer with immense knowledge and a passionate speaker about open source, blockchain, software products, and serverless technologies.