How do I query multiple images with gatsby-image?

后端 未结 4 1810
遥遥无期
遥遥无期 2021-02-05 19:05

I have 16 images that I want to render out onto a website in a grid format.

I\'m using the following plugins for this:

  • gatsby-image
  • <
相关标签:
4条回答
  • 2021-02-05 19:32

    Despite the situation in currently asked question, where all of 16 images are inside the images folder which is then easy to just run a query to fetch all possible images. Like this (accepted answer):

    {
      allImageSharp {
        edges {
          node {
            id
            fluid(maxWidth: 200, maxHeight: 200) {
                ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
    

    But in most cases you'd like to have subfolders inside the images folder for arranging images according to requirement. (At least that was my case).

    So in that case: (where you have images inside a subfolder let's say beach inside images you can follow this approach)

    export const query = graphql`
      query {
        allFile(filter: { relativeDirectory: { eq: "beach" } }) {
          edges {
            node {
              id
              childImageSharp {
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
    `
    

    This is a small egghead clip if you want to see in video.

    0 讨论(0)
  • 2021-02-05 19:38

    Here is a simple example with TypeScript and SVG support:

    Update gatsby-config.js

    module.exports = {
      plugins: [
        {
          resolve: `gatsby-source-filesystem`,
          options: {
            name: `images`,
            path: `${__dirname}/src/assets/images`,
          },
        },
      ],
    };
    

    Create Image Component

    import * as React from 'react';
    import { FC } from 'react';
    import { graphql, StaticQuery } from 'gatsby';
    import Img from 'gatsby-image';
    
    interface IProps {
      name: string;
      alt: string;
      className?: string;
    }
    
    const Image: FC<IProps> = ({ name, alt, className }) => (
      <StaticQuery
        query={graphql`
          query AllImages {
            allImagesWithoutSVGExtension: allFile(
              filter: {
                sourceInstanceName: { eq: "images" }
                extension: { regex: "/jpeg|jpg|png|gif/" }
              }
            ) {
              nodes {
                publicURL
                extension
                sharp: childImageSharp {
                  fluid {
                    originalName
                    ...GatsbyImageSharpFluid_withWebp
                  }
                }
              }
            }
            allImagesWithSVGExtension: allFile(
              filter: {
                sourceInstanceName: { eq: "images" }
                extension: { eq: "svg" }
              }
            ) {
              nodes {
                publicURL
                extension
              }
            }
          }
        `}
        render={({ allImagesWithoutSVGExtension, allImagesWithSVGExtension }) => {
          const isNameWithSVGExtension = name.indexOf('svg') !== -1;
    
          const renderImageWithSVGExtension = () => {
            const image = allImagesWithSVGExtension.nodes.find(
              ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
            );
            return image ? (
              <img
                className={className}
                src={image.publicURL}
                alt={alt}
                width={100}
                height={100}
              />
            ) : null;
          };
    
          const renderImageWithoutSVGExtension = () => {
            const image = allImagesWithoutSVGExtension.nodes.find(
              ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
            );
            return image && image.sharp && image.sharp.fluid ? (
              <Img className={className} fluid={image.sharp.fluid} alt={alt} />
            ) : null;
          };
    
          return isNameWithSVGExtension
            ? renderImageWithSVGExtension()
            : renderImageWithoutSVGExtension();
        }}
      />
    );
    
    export { Image };
    
    

    Use Image component as

    <Image name="logo.svg" alt="compony logo" />
    or
    <Image name="logo.png" alt="compony logo" />
    
    0 讨论(0)
  • 2021-02-05 19:41

    The easiest way is to create an image provider:

    import React from 'react'
    import { graphql, useStaticQuery } from 'gatsby'
    import Img from 'gatsby-image'
    
    const Image = ({ fileName, alt, style }) => {
      const { allImageSharp } = useStaticQuery(graphql`
        query {
          allImageSharp {
            nodes {
              fluid(maxWidth: 1600) {
                originalName
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
        }
      `)
    
      const fluid = allImageSharp.nodes.find(n => n.fluid.originalName === fileName)
        .fluid
    
      return (
        <figure>
          <Img fluid={fluid} alt={alt} style={style} />
        </figure>
      )
    }
    
    export default Image;
    

    And then, after importing, easily insert the image which you need:

    <Image fileName="yourImage.jpg" style={{ width: '100%' }} alt="" />
    
    0 讨论(0)
  • 2021-02-05 19:52

    Having a poke around in GraphiQL should help you, especially the Explorer. Although remember that Gatsby fragments won't work in GraphiQL.

    {
      allImageSharp {
        edges {
          node {
            id
            fluid(maxWidth: 200, maxHeight: 200) {
                ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
    

    So the above should be equal to something like the following query which will work in GraphiQL

    {
      allImageSharp {
        edges {
          node {
            id
            fluid(maxHeight: 200, maxWidth: 200) {
              src
              srcSet
              base64
              aspectRatio
              originalImg
              sizes        
            }
          }
        }
      }
    }
    

    Then your component can use this same query and render the results like this:

    import React from "react"
    import { graphql } from "gatsby"
    import Img from "gatsby-image"
    
    const imgGridStyle = {
      display: 'grid',
      gridTemplateColumns: `repeat(auto-fill, 200px)`
    };
    
    export default ({ data }) => (
      <div>
        <h1>Hello gatsby-image</h1>
        <div style={imgGridStyle}>
          {data.allImageSharp.edges.map(edge => 
            <Img fluid={edge.node.fluid} />
          )}
        </div>
      </div>
    )
    
    export const query = graphql`
      query {
        allImageSharp {
          edges {
            node {
              id
              fluid(maxWidth: 200, maxHeight: 200) {
                ...GatsbyImageSharpFluid
              }
            }
          }
        }
      }
    `
    

    You can easily loop over the resulting array of imageSharp nodes returned from the query in data.allImageSharp.edges.map. Then pass each node's fluid property, as the fluid prop to gatsby-image.

    Note: This renders every imageSharp node in your project, which may or may not be what you want to achieve.


    To filter the query by folder name, you could adjust the query like this:

    {
      allImageSharp(filter: {fileAbsolutePath: {regex: "/(myFolder)/"  }}) {
        edges {
          node {
            id
            fluid(maxWidth: 200, maxHeight: 200) {
                ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
    

    Have a look at the gatsby graphql reference for filter as to how you might perform other kinds of filters on the query.

    0 讨论(0)
提交回复
热议问题