How do I query multiple images with gatsby-image?

Having a poke around in GraphiQL should help you, especially the Explorer. Although remember that Gatsby fragments won't work in GraphiQL.

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

So the above should be equal to something like the following query which will work in GraphiQL

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxHeight: 200, maxWidth: 200) {
          src
          srcSet
          base64
          aspectRatio
          originalImg
          sizes        
        }
      }
    }
  }
}

Then your component can use this same query and render the results like this:

import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"

const imgGridStyle = {
  display: 'grid',
  gridTemplateColumns: `repeat(auto-fill, 200px)`
};

export default ({ data }) => (
  <div>
    <h1>Hello gatsby-image</h1>
    <div style={imgGridStyle}>
      {data.allImageSharp.edges.map(edge => 
        <Img fluid={edge.node.fluid} />
      )}
    </div>
  </div>
)

export const query = graphql`
  query {
    allImageSharp {
      edges {
        node {
          id
          fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  }
`

You can easily loop over the resulting array of imageSharp nodes returned from the query in data.allImageSharp.edges.map. Then pass each node's fluid property, as the fluid prop to gatsby-image.

Note: This renders every imageSharp node in your project, which may or may not be what you want to achieve.


To filter the query by folder name, you could adjust the query like this:

{
  allImageSharp(filter: {fileAbsolutePath: {regex: "/(myFolder)/"  }}) {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

Have a look at the gatsby graphql reference for filter as to how you might perform other kinds of filters on the query.


Here is a simple example with TypeScript and SVG support:

Update gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/assets/images`,
      },
    },
  ],
};

Create Image Component

import * as React from 'react';
import { FC } from 'react';
import { graphql, StaticQuery } from 'gatsby';
import Img from 'gatsby-image';

interface IProps {
  name: string;
  alt: string;
  className?: string;
}

const Image: FC<IProps> = ({ name, alt, className }) => (
  <StaticQuery
    query={graphql`
      query AllImages {
        allImagesWithoutSVGExtension: allFile(
          filter: {
            sourceInstanceName: { eq: "images" }
            extension: { regex: "/jpeg|jpg|png|gif/" }
          }
        ) {
          nodes {
            publicURL
            extension
            sharp: childImageSharp {
              fluid {
                originalName
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
        }
        allImagesWithSVGExtension: allFile(
          filter: {
            sourceInstanceName: { eq: "images" }
            extension: { eq: "svg" }
          }
        ) {
          nodes {
            publicURL
            extension
          }
        }
      }
    `}
    render={({ allImagesWithoutSVGExtension, allImagesWithSVGExtension }) => {
      const isNameWithSVGExtension = name.indexOf('svg') !== -1;

      const renderImageWithSVGExtension = () => {
        const image = allImagesWithSVGExtension.nodes.find(
          ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
        );
        return image ? (
          <img
            className={className}
            src={image.publicURL}
            alt={alt}
            width={100}
            height={100}
          />
        ) : null;
      };

      const renderImageWithoutSVGExtension = () => {
        const image = allImagesWithoutSVGExtension.nodes.find(
          ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
        );
        return image && image.sharp && image.sharp.fluid ? (
          <Img className={className} fluid={image.sharp.fluid} alt={alt} />
        ) : null;
      };

      return isNameWithSVGExtension
        ? renderImageWithSVGExtension()
        : renderImageWithoutSVGExtension();
    }}
  />
);

export { Image };

Use Image component as

<Image name="logo.svg" alt="compony logo" />
or
<Image name="logo.png" alt="compony logo" />

From Gatsby v3 you just need to use the gatsby-plugin-image plugin, which provides automatic image optimizations

import { StaticImage } from "gatsby-plugin-image"
export function Dino() {
  return (
    <StaticImage
      src="../images/dino.png"
      alt="A dinosaur"
      placeholder="blurred"
      layout="fixed"
      width={200}
      height={200}
    />
  )
}

More information: https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image

Gatsby v2:

The easiest way is to create an image provider:

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import Img from 'gatsby-image'

const Image = ({ fileName, alt, style }) => {
  const { allImageSharp } = useStaticQuery(graphql`
    query {
      allImageSharp {
        nodes {
          fluid(maxWidth: 1600) {
            originalName
            ...GatsbyImageSharpFluid_withWebp
          }
        }
      }
    }
  `)

  const fluid = allImageSharp.nodes.find(n => n.fluid.originalName === fileName)
    .fluid

  return (
    <figure>
      <Img fluid={fluid} alt={alt} style={style} />
    </figure>
  )
}

export default Image;

And then, after importing, easily insert the image which you need:

<Image fileName="yourImage.jpg" style={{ width: '100%' }} alt="" />

Despite the situation in currently asked question, where all of 16 images are inside the images folder which is then easy to just run a query to fetch all possible images. Like this (accepted answer):

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

But in most cases you'd like to have subfolders inside the images folder for arranging images according to requirement. (At least that was my case).

So in that case: (where you have images inside a subfolder let's say beach inside images you can follow this approach)

export const query = graphql`
  query {
    allFile(filter: { relativeDirectory: { eq: "beach" } }) {
      edges {
        node {
          id
          childImageSharp {
            fluid {
              ...GatsbyImageSharpFluid_withWebp
            }
          }
        }
      }
    }
  }
`

This is a small egghead clip if you want to see in video.

Tags:

Reactjs

Gatsby