Building a slideshow with Gatsby-Image and React Hooks
Jordan Jones.
・3 min read
GatsbyJS is one of my favourite technologies lately, It has made frontend development enjoyable again, but I've encountered some limitations (Not specific to Gatsby)
recently and it seems others have encountered similar issues. Namely, building a slideshow/carousel/multiple images with
gastbyjs and
gatsby-image.
TLDR; I built a "slideshow" of lazy loaded images, demo over at gatsby-slides
Disclaimer: This is pretty experimental and hacky and I'm fairly certain it can be improved, critiques are welcome.
Set up Gatsby and Gatsby-Image
Because
gatsby docs are so well done, it's fairly easy to get started and set up with a basic project. From your terminal, type
$ gatsby new gatsby-slide $ cd gatsby-slide
This creates a new gatsby project (with
gatsby-image already installed) from a starter template and changes directory after gatsby is done setting up files.
Now if we run
npm start and navigate to localhost:8000 we should see our gatsby site up and running.
We're all set to continue!
Querying Multiple Images
So thankfully, the template includes code to already query an image as shown below
//src/image.js const Image = () => ( <StaticQuery query={graphql` query { placeholder: file(relativePath: { eq: "gatsby-logo.png" }) { childImageSharp { fluid(maxWidth: 300) { ...GatsbyImageSharpFluid } } } } `} render={data => <Img fluid={data.placeholder.childImageSharp.fluid} />} /> )
This finds the image
gatsby-logo.png and lazy loads it with the
fragment
GatsbyImageSharp, read more about fragments and
gatsby-image here. But how do we
use this to query multiple images? I came across this lil gem while reading the other day, thanks to Kent C. Dodds for writing it.
graphql` query { allFile( sort: { fields: name, order: DESC } filter: { relativeDirectory: { eq: "slides" } } ) { edges { node { id name childImageSharp { fluid(maxWidth: 600) { ...GatsbyImageSharpFluid_withWebp_tracedSVG } } } } } }
Now that we have this query for getting multiple files, let's go ahead and wire this up with good ol hooks.
import { useStaticQuery, graphql } from 'gatsby' function SlideShow() { const [index, setIndex] = useState(0) const { allFile } = useStaticQuery( graphql` query { allFile( sort: { fields: name, order: DESC } filter: { relativeDirectory: { eq: "slides" } } ) { edges { node { id name childImageSharp { fluid(maxWidth: 600) { ...GatsbyImageSharpFluid_withWebp_tracedSVG } } } } } } ` ) //Minus 1 for array offset from 0 const length = allFile.edges.length - 1 const handleNext = () => index === length ? setIndex(0) : setIndex(index + 1) const handlePrevious = () => index === 0 ? setIndex(length) : setIndex(index - 1) const { node } = allFile.edges[index] return ( <div> <div> <Img fluid={node.childImageSharp.fluid} key={node.id} alt={node.name.replace(/-/g, ' ').substring(2)} /> </div> <div> <button onClick={() => handlePrevious()}>Previous</button> <button onClick={() => handleNext()}>Next</button> </div> </div> ) }
Some additional logic for handling next and previous slide but overall still a simple example.
Conclusion
Through the mystical powers of React Hooks and graphql, we can
useStaticQuery hook as well
as specifying a filter on our
allFiles to query to get all images in the
slides folder (where all the images for the slideshow are, duh Jordan). The result is pretty niffy, check out the demo gatsby-slides.
Did this interest you? Head over to jordnjones.com for more!
Why being a good programmer barely requires programming at all.
Yes, you read that right. To be a good programmer you don’t need to be good at programming. I hear what you’re saying, that makes no sense! Well hold on a second, hear me out.
