Search code examples
reactjswebpackgatsbyimage-loading

What is the best way to display all pictures of a directory in a Gatsby project using React?


I am using GatsbyJS starter https://www.gatsbyjs.org/starters/codebushi/gatsby-starter-forty/ and have a need to display all pictures from a directory on a page. Gatsby's recommended way to import media is to use import statement, but it results in hashes added to the file names after the build. For example: /static/pic09-d59e4b49832baeb9c62a7a9d6c070f8c.jpg

If I retrieve all filenames from a directory and try to create <img> elements with src={fileName} it results in empty images, because file names does not match with the ones from the server already with hashes appended.

Please recommend an elegant solution on how to go through this. My backup plan is to put everything to the static directory where hashes are not being added, but it is not recommended way by Gatsby documentation: https://www.gatsbyjs.org/docs/static-folder/

This is what I have now:

import React from 'react'
import Layout from '../components/layout'

class Gallery extends React.Component {
    render() {
        const images = [];
        const req = require.context('../assets/images/signboards', false);
        req.keys().forEach(function (key) {
            images.push(key.substr(1));
        });
        return (
            <Layout>
                <div id="main">
                    <section className="spotlights">
                        <section>
                            {images.map((image) => {
                                return (
                                <div className="image">
                                <img src={'../assets/images/signboards' + image} alt="" />
                            </div>
                                )
                            })}
                        </section>
                    </section>
                </div>
            </Layout>
        )
    }
}

export default Gallery;

Thank you


Solution

  • Note: this answer assumes you have already installed gatsby-source-filesystem, gatsby-transformer-sharp and gatsby-plugin-sharp.


    You can use a graphql page query to get all of the files of a certain extension, in a certain folder by filtering allFile with a combination of regular expression matchers.

    Then you can loop through the resulting edges and use gatsby-image to display the image.

    import React from "react"
    import { graphql } from "gatsby"
    import Img from 'gatsby-image'
    
    const IndexPage = ({data}) => (
      <>
        {data.allFile.edges.map(edge => {
          return <Img fluid={edge.node.childImageSharp.fluid} />
        })}
      </>
    )
    
    export default IndexPage
    
    export const indexQuery = graphql`
      query AssetsPhotos {
        allFile(filter: {extension: {regex: "/(jpg)|(jpeg)|(png)/"}, dir: {regex: "/assets/images/signboards"}}) {
          edges {
            node {
              id
              childImageSharp {
                fluid(maxWidth: 300) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    `