3

I have been working with Gatsby and GraphQL on a project for a bit now. This is my first time using this platform so still figuring out the right way to go about it.

Right now, I have an index.js which loads a list of users from a GraphQL query such as

  allUserList {
      users {
        name
        imageUrl
    }
  }
}

imageUrl is expected to send the correct file path i.e images/image.png This is sent directly to a react component which is used to display the user info

const Users = {data} => {
  return (
    data.users.map(user => {
      return (
        <User name={user.name} imageUrl={user.imageUrl}/>
      )
    }
  )
}

What I am trying to figure out now is, imageUrl contains the relative url to the image in the codebase. I would be required to run a image query on this url to get the image object which I can then pass to gatsby image. Something like this

{
  image: file(relativePath: { eq: 'image.png' }) {
    childImageSharp {
      fixed(width: 160, height: 160) {
        ...GatsbyImageSharpFixed
      }
    }
  }
}

However as I understand it isnt possible to parameterize the image url here. What is the best way to go about this? Is this even the correct approach to show a list with images in this manner?

Anurag Ramdasan
  • 4,189
  • 4
  • 31
  • 53

1 Answers1

2

However as I understand it isnt possible to parameterize the image url here.

Correct. Gatsby runs GraphQL queries ONCE at build time and then never again until you gatsby develop or gatsby build again.

Two approaches:

First approach: You name your images after user.name. You can then query all your images and filter for each user by file name using the graphQL originalName attribute:

const UserSupplier = () => {
  const { allFile } = useStaticQuery(graphql`
    query {
      allFile(filter: {
        extension: {regex: "/(jpg)|(jpeg)|(png)/"}, 
        sourceInstanceName: {eq: "user"}}) 
      {
        edges {
          node {
            childImageSharp {
              fluid(maxWidth: 150, quality: 100) {
                originalName
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }`);
  const user = users.filter(el => el.userId === userId)[0];
  const { fluid } = user .node.childImageSharp;

  return (
    <UserComponent>
      <GatsbyImage fluid={fluid} alt={fluid.originalName} />
    </UserComponent>
  );
};

Second approach: Query for your childImageSharp image object in your allUserList query. You can pass the image as props to the component that renders the image. That would make your query result query quite data intensive depending on how many users there are.

  allUserList {
      users {
        name
        imageUrl
        childImageSharp { // the query path is probably wrong since I don't know your project
          fixed(width: 160, height: 160) {
            ...GatsbyImageSharpFixed
        }
      }
    }
  }
}
EliteRaceElephant
  • 7,744
  • 4
  • 47
  • 62
  • I was hoping there were a way to parameterize something like this perhaps, but this works well too! – Anurag Ramdasan Mar 01 '20 at 03:19
  • I have seen multiple similar answers on many places, one thing I don't understand is where do you provide the url to image in the second solution? How does graphql know from where to fetch the image? – Ankur Parihar Aug 30 '21 at 11:35