Gatsby with WPGraphQL, ACF and Gatbsy-Image
So, there is a lot happening around Gatsby with WordPress and WPGraphQL. At times, it can get confusing and a lot of given functionality is hard to find or figure out. I am working on a client project right now and somehow had to handle images, that I source through my WordPress backend.
After trying out all sorts of solutions and working through the plugin library of Gatsby, I ended up finding a little piece of documentation, that led me to a solution, that works for me. And, because some very helpful people in the WPGraphQL Slack Chat asked me to write about that solution … here I am.
I simply wanted to have my WordPress Media as static files inside my Gatsby app and work with the gatsby-image plugin for transformation/optimization.
Libraries used
- GatsbyJs
- WordPress
Gatsby Config
/* --------- gatsby-config.js --------- */
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/assets/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: "gatsby-source-graphql",
options: {
typeName: "WPGraphQL",
fieldName: "wpgraphql",
url: `https://${YOUR_DOMAIN}/graphql`,
},
},
]
}
- Make sure all the plugins are mentioned correctly in your config file
- For some reason, it can cause errors not having
gatsby-source-filesystem
used in the configs. Make sure it resolves to a valid path, even if there are no images inside the folder.
Gatsby Node
/* --------- gatsby-node.js --------- */
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.createResolvers = (
{
actions,
cache,
createNodeId,
createResolvers,
store,
reporter,
},
) => {
const { createNode } = actions
createResolvers({
WPGraphQL_MediaItem: {
imageFile: {
type: `File`,
resolve(source, args, context, info) {
return createRemoteFileNode({
url: source.sourceUrl,
store,
cache,
createNode,
createNodeId,
reporter,
})
},
},
},
})
}
That’s really all you need. Let’s break it down a little:
WPGraphQL_MediaItem
: This depends on your config. It starts with thetypeName
of your gatsby-source-graphql.- createRemoteFileNode gives you the ability to pull in remote files and automatically adds them to your schema.
imageFile
: will be the type you can query (see below).type: 'File'
: will add the MediaItems as Files, which is great, because now gatsby-image can make use of it.url: source.sourceUrl
: Is the images Url coming from your WordPress
Pages Query
# page.js
query {
WPGraphQL {
pages {
nodes {
featuredImage {
sourceUrl
imageFile {
childImageSharp {
fixed {
...GatsbyImageSharpFixed
}
}
}
}
}
}
}
}
Important: Always query sourceUrl
, otherwise it doesn’t work, because the resolver would miss that data.
Final thoughts
Thats all there is to it. And it works with ACF Media files too. Same same.
Almost … I think it is important to mention, that with this method all available Media-Files coming from WordPress will be pulled in the cache. So, if there is, for some reason, a clear of the cache happening, it would need to pull them in again I guess. For performance, it could still be more useful to somehow fetch all the Media-Files apart from the Gatbsy-Cache. That would mean though, you have to do the hard work of creating the schema yourself. I’m sure there will be great solutions for that too. Would be happy if someone has some experience with that and would share their thoughts 🙂
Caching
If your server doesn’t support etags, the default caching of the gatsby-source-filsystem
won’t work.
You can checkout the custom solution by Robert Marshall here, which should be slightly faster and doesn’t rely on etags: https://thoughtsandstuff.com/gatsby-with-wordpress-caching-downloaded-media-images-to-reduce-build-time/
Coming Up
I plan on writing up a big article about setting up Gatbsy + WordPress + ACF + Polylang for a client ready project with Multilanguage-Support and dynamic content creation through ACF’s flexible content fields. I wonder if that would be of interest. Any thoughts and suggestions are highly appreciated.
References
See the Gatsby documentation of it here: https://www.gatsbyjs.org/docs/schema-customization/#feeding-remote-images-into-gatsby-image