Search code examples
javascriptreactjsgraphqlgatsbygatsby-image

Importing and displaying multiple images from GraphQL using gatsby-plugin-image


Hi I'm trying to add an instagram feed to my website but I can not find a way to make it work. I haven't really used these tools before so I don't really understand it, but made it to point where I think I have the feed in GraphQL. Now the problem is I don't know how to display the images. Can anyone help?

Here is some code:

import React from "react"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import { useStaticQuery, graphql } from "gatsby"


const CapabilityList = () => {
  const data = useStaticQuery(graphql`
  query InstagramQuery {
    allInstagramContent {
      edges {
        node {
          localImage {
            
            childImageSharp {
              fixed(width: 200, height: 200) {
                ...GatsbyImageSharpFixed
              }
          }
        }
      }
    }
  }
}
`)
  let arrayOfInstaImages = getImage(data, 'allInstagramContent.edges')

  return (
      <div style={{ maxWidth: `900px`, marginBottom: `1.45rem`, display: 'flex' }}>
        {arrayOfInstaImages.map((item, i) => {
          return (
            <div key={i} style={{ width: "200px", height: "200px" }}>
              <GatsbyImage image={item.node.localImage.childImageSharp.fixed} />
            </div>)
        })}
      </div>

  )
}

export default CapabilityList;

This doesn't work and displays error: Property 'map' does not exist on type 'IGatsbyImageData'.
So I think I need some other way to display a few images from the array.

Thanks a lot for every help!


Solution

  • getImage is a helper function (you don't really need it) that returns an image object given a path. Not an array:

    Safely get a gatsbyImageData object. It accepts several different sorts of objects, and is null-safe, returning undefined if the object passed, or any intermediate children are undefined.

    Simply do:

      return (
          <div style={{ maxWidth: `900px`, marginBottom: `1.45rem`, display: 'flex' }}>
            {data.allInstagramContent.edges.node.map((item, i) => {
              return (
                <div key={i} style={{ width: "200px", height: "200px" }}>
                  <Img image={item.node.localImage.childImageSharp.fixed} />
                </div>)
            })}
          </div>
      )
    

    Note: Img for gatsby-image

    Your array of iterable data is the node so you should look and loop there (you can console.log it to help you understand the data structure).

    The main problem in your code, besides the wrong loop, is that you are using a GraphQL query structure for Gatsby Image (from version 2, Img from gatsby-image) while you are using GatsbyImage component (from v3 onwards, GatsbyImage from gatsby-image-plugin). You can check for the migration details at: https://www.gatsbyjs.com/docs/reference/release-notes/image-migration-guide/

    If you want to use a GatsbyImage, your code should look like:

    import React from "react"
    import { GatsbyImage, getImage } from "gatsby-plugin-image"
    import { useStaticQuery, graphql } from "gatsby"
    
    
    const CapabilityList = () => {
      const data = useStaticQuery(graphql`
      query InstagramQuery {
        allInstagramContent {
          edges {
            node {
              localImage {
               gatsbyImageData(
                 width: 200
                 placeholder: BLURRED
                 formats: [AUTO, WEBP, AVIF]
               )
              }
            }
          }
        }
      }
    }
    `)
    
          return (
              <div style={{ maxWidth: `900px`, marginBottom: `1.45rem`, display: 'flex' }}>
                {data.allInstagramContent.edges.node.map((item, i) => {
                  return (
                    <div key={i} style={{ width: "200px", height: "200px" }}>
                      <GatsbyImage image={item.node.localImage.childImageSharp.gatsbyImageData} />
                    </div>)
                })}
              </div>
          )
    }
    
    export default CapabilityList;
    

    Note: the use of Img or GatsbyImage will strictly rely on your installed packages and your gatsby-config.js structure. Check it out because you are mixing concepts.

    Both components are similar but they accept different image props. While GatsbyImage accepts an image prop containing gatsbyImageData, Img accepts a fluid/fixed prop of childImageSharp (fluid or fixed) data, so the query will be slightly different depending on the component used so as it should be the configuration.

    Of course, this is an approximation. Your GraphQL structure may be slightly different depending on your data structure. Check the query at the GraphiQL playground (localhost:8000/___graphql)