How To Query Gatsby Images with GraphQL
Kyle Luke
Posted on January 6, 2021
When learning new tools, often times the most challenging parts will lead to the coolest features and benefits. This was the case for me when learning to use Gatsby, and how GraphQL works. I struggled hard at figuring out how to use the gatsby-image
plugin, and how to query GraphQL assets to display individual images on in the correct spot.
So why Gatsby (and why Gatsby Image)?
For many reasons React developers are choosing to use static site generator such as Gatsby or Next.js. Static site generators create blazing fast single page applications, and also allow for a quicker and simplified development process with multiple available plugins. One plugin that Gatsby does very well is Gatsby-images. Gatsby-images is a react component that lazy-loads images with a blur-up effect, speeding up page loading times dramatically and holding image positions until loaded. The benefits of using Gatsby Images were a major benefit for my portfolio site, so I opted to learn how querying in GraphQL works so I would then be able to individually place a fast loading Gatsby Image on demand.
Traditional React Image Example
The original way to import an image into React is through
import example from '../images/example.jpg'
<img className="example" src={example}/>
and produces an image that slowly loads from the top down before displaying.
Gatsby Image Example
Gatsby Images are lazy-loaded, starting with the full image visible and a blur effect applied. As the browser has time to download, the image scales up until full resolution.
Image from CSS Tricks: Ways to Organize and Prepare Images for a Blur-Up Effect Using Gatsby
Pretty cool, huh!?
How To Query Gatsby Images with GraphQL
1. Install the Gatsby Image plugin
npm install gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp
2. Add Gatsby Image plugin to Gatsby Config file
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: { name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`
, ...additionalplugins
]
3. Add your images to /src/images
folder
The images folder will be mapped in our query later on to select individual images for conversion and import.
4. Import Gatsby Image component and GraphQL into Gatsby page file
import { graphql } from "gatsby"
import Img from "gatsby-image"
5. Query GraphQL to select image/images and convert to Gatsby Images
export const fluidImage = graphql`
fragment fluidImage on File {
childImageSharp {
fluid(maxWidth: 1600) {
...GatsbyImageSharpFluid
}
original {
width
}
}
}
`;
export const pageQuery = graphql`
query {
projectHero: file(
relativePath: { eq: "exampleHero.jpg" }
) {
...fluidImage
}
imageOne: file(
relativePath: { eq: "examplephoto-1.jpg" }
) {
...fluidImage
}
imageTwo: file(
relativePath: { eq: "examplephoto-2.jpg" }
) {
...fluidImage
}
imageThree: file(
relativePath: { eq: "examplephoto-3.jpg" }
) {
...fluidImage
}
imageFour: file(
relativePath: { eq: "examplephoto-4.jpg" }
) {
...fluidImage
}
}
`;
6. Import Gatsby Image tag into page and position/style with CSS
<Img fluid={props.data.file.childImageSharp.fluid} />
Full Component Example
import React, { Component } from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { graphql } from 'gatsby';
import Img from 'gatsby-image';
const pageId="example"
export const fluidImage = graphql`
fragment fluidImage on File {
childImageSharp {
fluid(maxWidth: 1600) {
...GatsbyImageSharpFluid
}
original {
width
}
}
}
`;
export const pageQuery = graphql`
query {
projectHero: file(
relativePath: { eq: "exampleHero.jpg" }
) {
...fluidImage
}
imageOne: file(
relativePath: { eq: "examplephoto-1.jpg" }
) {
...fluidImage
}
imageTwo: file(
relativePath: { eq: "examplephoto-2.jpg" }
) {
...fluidImage
}
imageThree: file(
relativePath: { eq: "examplephoto-3.jpg" }
) {
...fluidImage
}
imageFour: file(
relativePath: { eq: "examplephoto-4.jpg" }
) {
...fluidImage
}
}
`;
class Example extends Component {
render() {
return (
<Layout>
<SEO title={pageId} />
<div
className="hero project-hero d-flex align-items-center"
style={{
backgroundSize: "cover",
backgroundPosition: "50% 65%",
overflow: "hidden",
}}
>
<Img
fluid={this.props.data.projectHero.childImageSharp.fluid}
imgStyle={{ objectFit: "cover" }}
alt="Example project hero image."
/>
</div>
<Card className="no-radius">
<Img
fluid={this.props.data.imageOne.childImageSharp.fluid}
imgStyle={{ objectFit: "cover" }}
alt="Example project example image."
/>
<Img
fluid={this.props.data.imageTwo.childImageSharp.fluid}
imgStyle={{ objectFit: "cover" }}
alt="Example project example image."
/>
<Img
fluid={this.props.data.imageThree.childImageSharp.fluid}
imgStyle={{ objectFit: "cover" }}
alt="Example project example image."
/>
<Img
fluid={this.props.data.imageFour.childImageSharp.fluid}
imgStyle={{ objectFit: "cover" }}
alt="Example project example image."
/>
</Card>
</Layout>
)}}
export default Example
Other Thoughts
Making Gatsby Image a component, and passing URL path as props.
To consolidate and DRY up multiple pages that might put into use the same Gatsby Image queries, you can create a component with the Gatsby Image query, and pass URL paths as props.
Using Flexbox vs Float (Float breaks Gatsby Image)
One issue developers might notice while implementing Gatsby Images is that they break with the use of CSS float properties. To overcome this issue, many developers make use of Flexbox instead of float, to shape and align images on the page.
https://dev.to/steelvoltage/struggling-with-gatsby-images-1ao5
Run Gatsby Development Server and view GraphQL Playground
The Gatsby GraphQL playground is particularly fun to play around with and test your queries. It will help you identify what is being held in your GraphQL data and how to get to it, and doing some digging around will help you understand how GraphQL queries work.
To view the playground, run your Gatsby development server and visit: http://localhost:8000/___graphql
Making it Work
I got stuck several times during the process of trying to query through my images with GraphQL, and then again displaying them correctly as Gatsby Images. Hopefully this post guides you through querying GraphQL for your own Gatsby project, and how to display images correctly using the benefits of Gatsby Images.
Did you find this helpful? If you have used Gatsby Image, what got YOU stuck while learning?
Additional Resources
- Image Optimization Made Easy with Gatsby
- Rewriting A Static Website Using Gatsby and GraphQL - Part 3
- Optimizing Images with Gatsby Image
- Gatsby Docs: Using Gatsby Image to Prevent Image Bloat
- Gatsby Docs: Gatsby Image Demo
- CSS Tricks: Ways to Organize and Prepare Images for a Blur-Up Effect Using Gatsby
Posted on January 6, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.