1

I'm using the gatsby-image plugin to display images on my Gatsby site. In my GraphQL query, I want to be able to pass in a variable to the relativePath argument as this query is being run (in the parent component) for a number of components that require images. I cannot seem to figure out how to do this though.

This is what my query looks like:

...

const imgData = useStaticQuery(graphql`
        query{
            file(relativePath: {eq: "talent.png"}) {
                childImageSharp {
                    fixed (width: 289, height: 589) {
                        ...GatsbyImageSharpFixed
                    }
                }
            }
        }
    `)

I want to replace that "talent.png" with a variable so I can use this query across components. This is my desired query:

const imgData = useStaticQuery(graphql`
        query($pageImg: String!){
            file(relativePath: {eq: $pageImg}) {
                childImageSharp {
                    fixed (width: 289, height: 589) {
                        ...GatsbyImageSharpFixed
                    }
                }
            }
        }
    `)

I have tried adding a context to the page using onCreatePage in gatsby-node.js. This would work for a page query but the file node obviously does not recognise page context. So I tried adding a context to the file node:

module.exports.onCreateNode = ({ node, actions }) => {
    const { createNodeField } = actions

    if(node.internal.type === 'File'){
        createNodeField({
            node,
            name: 'context',
            value: {
                pageImg: node.relativePath
            }
        })
    }
}

But still I get this error: Variable "$pageImg" of required type "String!" was not provided.

Any help in understanding how to solve this issue will be greatly appreciated.

divergent
  • 271
  • 4
  • 17
  • 2
    I know off the bat that variable are not supported in useStaticQuery per https://www.gatsbyjs.org/docs/use-static-query/#known-limitations. I'm not quite clear where you hoped to get the files paths data from to use in the query in the $pageImg variable, but I'm wondering if you couldn't use the allFileSharp query (maybe with filter), to get multiple images, and then pass these to child components. – Jacob Goodwin Aug 10 '19 at 03:38
  • Yes, I actually ended up using `allFile` and querying for the name, and then using that to filter in my code – divergent Aug 10 '19 at 08:15
  • 1
    if you have a lot of images, querying `allFile` in a component may significantly increase the size your `page-data.json` & leads to slower load time -- it's best to just be specific in your page query – Derek Nguyen Aug 10 '19 at 18:41

1 Answers1

0

I was converting a project from Nextjs to Gatsby basically because of the cool plugins gatsby offers so i ran into the same issue because i loved the way gatsby-image pre-renders images.

I came across this issue but i had to refactor it to use the new useStaticQuery hook so your final code should look like this:

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

const Image = ({ style, alt, src, className }) => {
  const data = useStaticQuery(graphql`
    query {
      images: allFile {
        edges {
          node {
            relativePath
            name
            childImageSharp {
              fluid(maxWidth: 600) {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  `);

  const image = data.images.edges.find(img => img.node.relativePath.includes(src));
  if (!image) return null;

  return <Img fluid={image.node.childImageSharp.fluid} alt={alt} style={style} className={className} />;
};

Using the Image component:

import Image from '../components/image'
<Image
    src="gatsby-astronaut.png"
    alt="astronaut"
    className="w-full hidden md:block lg:-ml-8 rounded shadow-xl z-10"
/>
Divine Hycenth
  • 620
  • 6
  • 11