Reputation: 3447
I am trying to add a resume button on my about page, where the user can download my resume.
I have created a static folder as the documentation says in the root (src/static/myresume.pdf
) and then I have an href
like this:
<a href={`myresume.pdf`} download className="btn about-resume-button">Download my CV</a>
The file downloads correctly however when trying to open it, it is always corrupt. I tried doc, docx
and pdf
and all the same problem.
I am running locally at the moment on localhost, however it should still work.
Anything wrong that stands out?
I also saw from the documentation that you can query for a File in GraphQL using gatsby-source-filesystem
however I do not know how to do that yet.
Any help will be very much appreciated!
Thanks
Upvotes: 1
Views: 480
Reputation: 29325
You have a mistake in your static folder structure. It should be in your root folder (same level as /src
), not inside /src
. An ideal structure should look like:
/
|-- /.cache
|-- /plugins
|-- /public
|-- /src
|-- /pages
|-- /templates
|-- html.js
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js
Note: more details in Gatsby Project structure.
Fixing this structure mistake your code will work because your href
is pointing to the correct URL.
However, the approach that mention and shown in the Importing Assets Directly into Files documentation will optimize your code since it will make the PDF belong to the Gatsby environment.
To use the Gatsby filesystem you need to reference the file and give them a sourceInstanceName
. In your gatsby-config.js
:
{
resolve: `gatsby-source-filesystem`,
options: {
name: `pdf`,
path: `${__dirname}/src/pdf/`,
},
},
Note: this example assumes that your PDF will be under /src/pdf
folder. In addition, you can find more information about the gatsby-source-filesystem
in their documentation.
This will make your /src/pdf
folder available to query via GraphQL by creating a node for each file. The next step is to query it in your component/page:
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Layout from "../components/layout"
const DownloadsPage = () => {
const data = useStaticQuery(graphql`
{
allFile(filter: { sourceInstanceName: { eq: "pdf" } }) {
edges {
node {
publicURL
name
}
}
}
}
`)
return (
<Layout>
<h1>All PDF Downloads</h1>
<ul>
{data.allFile.edges.map((file, index) => {
return (
<li key={`pdf-${index}`}>
<a href={file.node.publicURL} download>
{file.node.name}
</a>
</li>
)
})}
</ul>
</Layout>
)
}
export default DownloadsPage
Basically with the snippet above, you are retrieving all files with sourceInstanceName
that matches "pdf" and looping through them. Querying for the publicURL
field of File
nodes will provide URLs you can use in your JavaScript components, pages, and templates.
You can omit the loop and point directly to your resume if you only have one by:
<div>
<a href={data.allFile.edges[0].file.node.publicURL}>{data.allFile.edges[0].file.node.name}</a>
</div>
Upvotes: 3