gatsbygatsby-image

getImage by Gatsby Image plugin returns undefined


I have hero image that I want to query for multiple times and fetch it in different sizes so I can use it in different devices sizes.

My hero image is in

src/images/hero.png

This is the query code:

export const mobileHeroImage = graphql`
  fragment mobileHeroImage on File {
    childImageSharp {
      fluid(maxWidth: 375, maxHeight: 400) {
        ...GatsbyImageSharpFluid
      }
    }
  }
`;

export const query = graphql`
  query {
    mobileHeroImage: file(relativePath: { eq: "hero.png" }) {
      ...mobileHeroImage
    }
  }
`;

This is my component's code in index.js:

const IndexPage = ({ data }) => {

  // First console log
  console.log(data);

  // Second console log
  console.log(getImage(data.mobileHeroImage));

First console log logs the object with the image object:

enter image description here

The second console log logs undefined even though there is mobileHeroImage object inside of data

The image in multiple dimensions would be passed as an array like this:

export function MyImage({ data }) {
  const images = withArtDirection(getImage(data.mobileHeroImage), [
    // I would add more sizes here for different screen sizes
    {
      media: "(max-width: 1024px)",
      image: getImage(data.smallImage),
    },
  ])
  return <GatsbyImage image={images} />
}

Solution

  • You are mixing concepts from gatsby-image (from Gatsby v2 backwards) and gatsby-plugin-image (from Gatsby v3 onwards).

    Among a lot of stuff, in the new version, they get reduced as Img (v2) and GatsbyImage (v3). The first one takes a fluid or a fixed props image data like the one you are querying in your fragment (...GatsbyImageSharpFluid) while GatsbyImage takes the whole image props data. They are queried differently.

    In addition, getImage is a helper function, so it's not mandatory despite it is making your code cleaner. The fact is from GatsbyImage (v3), that's why it's returning undefined in your code.


    Check the migration guide for further details: https://www.gatsbyjs.com/docs/reference/release-notes/image-migration-guide/


    That said, you should choose one version or another depending on your requirements. I'd suggest the new version because gatsby-image it's currently deprecated (so double-check it and get rid of the deprecated packages).

    Following the GatsbyImage approach, your query should look like:

    export const mobileHeroImage = graphql`
      fragment mobileHeroImage on File {
         childImageSharp {
           gatsbyImageData(
             width: 200
             placeholder: BLURRED
             formats: [AUTO, WEBP, AVIF]
           )
         }
      }
    `;
    
    export const query = graphql`
      query {
        mobileHeroImage: file(relativePath: { eq: "hero.png" }) {
          ...mobileHeroImage
        }
      }
    `;
    

    Note: tweak the query options and parameters as you wish

    Now, your console.logs should work.

      // First console log
      console.log(data);
    
      // Second console log
      console.log(getImage(data.mobileHeroImage));
    

    As I said, you can omit the getImage helper function and use directly data.