0

So I created a reusable hero section in React and I retrieve the images from a data file, so all I need to do to update the new image is I just update my data file. I'm trying to convert this component into Gatsby, but I'm not sure how to implement their images plugin with my data file.

My image component returns all my images with this code rn

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

          return (
            <>
              {data.allImageSharp.edges.map(edge => (
                <Img fluid={edge.node.fluid} />
              ))}
            </>
          )
        }

Below is my React code that I'm trying to convert to use gatsby

My data file is just an object that links the image I want to use

 export const heroSectionOne = {
  img: require('../../images/profile.jpg'),
   alt: 'Image',
   start: 'true'
 };

 export const heroSectionTwo = {
  img: require('../../images/house.jpg'),
   alt: 'Image',
   start: 'true'
 };

For now, I just pass in the props on the component

       <ImgWrapper start={start}>
            <Img src={img} alt={alt} />
          </ImgWrapper>

Then in my home page component, I will reuse the component, but switch which data file is used, so I get a different image

  <InfoSection {...heroSectionOne} />
  <InfoSection {...heroSectionTwo} />

So right now, my component will display img '../../images/profile.jpg' and the second section will display the house.jpg picture because I have it hard coded in my data file, but with Gatsby, how would I replicate this same method with their image component?

How would I write my image component in gatsby to be able to just pass in the image component anywhere in my app and then add whichever image I want to use in the component I end up adding it to?

I've only seen tutorials showing how to add a specific image to your query or how to display all your images in your folder at one time, but haven't seen anything about passing it through a data file

designxd10
  • 57
  • 8

1 Answers1

0

It's tricky to work like that with Gatsby's Image. However, I must say that you can bypass it in different ways depending on the filesystem used and how the data is structured.

Keep in mind that if you set properly the filesystem in your gatsby-config.js, you are allowing Gatsby to recognize and to find all your images in your project, making them queryable and allowing them to be used by Gatsby Image component.

const path = require(`path`)

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: path.join(__dirname, `src`, `images`),
      },
    },
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],
}

You can find much better ways than querying each image in a staticQuery filtered by the path, it's not true that is the only way to achieve it. Of course, if you are using a staticQuery approach, the limitation of making it dynamic forces you to make each query separately.

First of all, you need to know the difference between staticQuery and page query to understand which fits you and the limitations of them.

If you use a page query, you can always create an approach like the following one:

import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'

class ProductPage extends React.Component {
  render() {

    const products = get(this, 'props.data.allDataJson.edges')

    return (
      <Layout>
        {products.map(({ node }) => {
          return (
            <div key={node.name}>
              <p>{node.name}</p>
              <Img fluid={node.image.childImageSharp.fluid} />
            </div>
          )
        })}
      </Layout>
    )
  }
}

export default ProductPage


export const productsQuery = graphql`
  query {
    allDataJson {
      edges {
        node {
          slug
          name
          image{
            publicURL
            childImageSharp{
              fluid {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    }
  }
`

In the example above, you are using a page query to retrieve all images from a JSON file. If you set the path in your filesystem, you will be able to retrieve them using the GraphQL fragments. This approach is the more dynamic you can afford when dealing with Gatsby Image and it's better to query one by one.

The idea remains the same for other filesystems, this is just an adaptable approach. If you are using a CMS like Contentful, you can download the assets and query them dynamically in the same way since the filesystem allows you to do it.

Pages queries are only allowed in page components (hence the name) so, if you want to use it in a React standalone component to make it reusable, you will need to pass via props (or reducer) to your desired component and render the Gatsby image based on the received props.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67