Search code examples
reactjsgatsbygraphql-js

Gatsby & GraphQL - render a download link from a queried file


I'm building a static website with Gatsby and I need to put some .txt or .pdf files on it, so that a visitor can download them. How can I do it?

I'm a newbie, and my GraphQL knowledge is really thin, I use it only to get some images to my components. My 'gatsby-config.js' contains this:

{
  resolve: `gatsby-source-filesystem`,
  options: {
    name: `documents`,
    path: `${__dirname}/src/documents`,
  },
},

I tried something and on GraphiQL this seems to be valid code:

const data = useStaticQuery(graphql`
    query {
      document1: file(relativePath: {eq: "doc1.txt"}) {
        id
      }
    }
`) 

But I don't know how to make that 'document1' downloadable in JSX.


Solution

  • It is always worth looking in the GraphiQL explorer to see what is available to query. Then you can just follow the example of the static query in the default starter's image component.

    If you are using Gatsby > v2.1, you can do this with the useStaticQuery hook.

    import React from "react"
    import { useStaticQuery, graphql } from "gatsby"
    
    const Download = () => {
      const data = useStaticQuery(graphql`
        query MyQuery {
          file(relativePath: {eq: "doc1.txt"}) {
            publicURL
            name
          }
        }
      `)
      return <a href={data.file.publicURL} download>Download {data.file.name}</a>
    }
    
    export default Download
    

    If not, you can do this with Static query

    import React from "react"
    import { StaticQuery, graphql } from "gatsby"
    
    const Download = () => (
      <StaticQuery
        query={graphql`
          query MyQuery {
            file(relativePath: {eq: "doc1.txt"}) {
              publicURL
              name
            }
          }
        `}
        render={data => <a href={data.file.publicURL} download>Download {data.file.name}</a>}
      />
    )
    
    export default Download