The Headless Stack: WordPress, GraphQL and Gatsby

Sunday January 10th, 2021

For years I’ve been building sites with WordPress. The PHP page templating, media library, and The Loop was the holy trinity for me when I first got started with web development. Later, open-source tools like Trellis helped me speed up my development process by automating server provisioning. Sage, helped by speeding up starter theme development even faster. Now we have new paradigms such as the WP REST API and Gutenberg. We can more easily and more speedily, piece together custom blocks for editors. Every week, WordPress is inching closer and closer to becoming an agnostic CMS.

Static PHP page generation in WordPress is pretty good out of the box. But these days, everyone and their mom wants to write JSX. So, what’s the solve here? WordPress is deeply intertwined with PHP, and themes are not exactly prepped to work well with React. One could simply start with React and Redux and you’d probably end up with something like this. Not a terrible solution, albeit still a theme-based approach, not exactly performant, and the reducers alone give me a headache. Those would be firing quite frequently. We could be more efficient.

Enter Gatsby, or if you’re really saavy, you could opt for Next.js. Postlight has probably the most promising starter repo I have ever seen for Next.js. In this post I’ll be going over Gatsby specifically, but I definitely want to explore other avenues as well. The Jamstack, as it has come to be known is here in full-force, and it works really well. So, naturally I want to get my hands on some other approaches.

To get started, all you just need a Gatsby site, a data store, and a means to deploy it. Some prefer Netlify, others prefer Now. To be honest, they’ll all fairly inexpensive these days, if not free. But hosting your data store will cost you some dough. You don’t have to break the bank though. The cheapest Droplet on DigitalOcean (which is roughly ~$5/month) should more than suffice.

I setup my WordPress installation here at but, Postlight’s approach is interesting and notable, they have their WordPress served out of port 8080. As far as I can tell, you can’t do that with Gatsby. Not a deal breaker for me, but something for you to know. So, for the WordPress + Gatsby stack to work you’ll need to setup your API url under a sub domain (or separate domain I found want) at something like or if you want to follow me, works too.

Next, there’s a lot of configuring you need to do according to their blog post tutorial. Namely, you’ll need to install some plugins on your WordPress site to expose your WordPress Data to GraphQL:

Those two should suffice for a basic setup. Next, you’re going to have to configure your gatsby-config.js file a little bit in your Gatsby site repo. You can download this gatsby-starter-wordpress-blog and fork it. We just need to designate that API url here:

module.exports = {
  plugins: [
        resolve: `gatsby-source-wordpress-experimental`,
        options: {
            // the only required plugin option for WordPress is the GraphQL url.
            url: process.env.WPGRAPHQL_URL || ``,

As you can see here, gatsby-source-wordpress is currently in beta, so it carries the -experimental slug in the Gatsby Plugin name until v4 ships. But at a minimum, this is all you need to get started. From here, you can create pages in src/pages and GraphQL queries to hydrate your views with content.

I won’t go further than here in terms of setup, because really, the world is your oyster from here. After you fork the starter blog, you just run yarn && gatsby develop, clear up any GraphQL errors, and your local Gatsby site should run at localhost:8000, and your GraphQL playground runs at localhost:8000/___graphql

I would recommend reading up on how Gatsby routing works, and how to write (and inspect) GraphQL queries. Those two skills will give you the power to craft whatever kind of site you want.

Now, with Gatsby, it runs all the GraphQL queries at build-time. So, when you deploy to Netlify or Now or wherever, all the pages/posts and content are generated ahead of time. The inverse would be having the client render content at run-time. Dynamic pages are neato, but they are dreadfully slow. With this setup, we can have both! For static content (think like, blog posts or pages), we can use Gatsby’s static build capabilities. But if you need dynamic content (imagine comments, or loading things in real-time), you can leverage something like @apollo/client. With Apollo, you can fetch and run queries at run-time. That’s what I use to power my personal bookmarks!

Suggested reading:

I imagine I’ll continue writing more about this headless revolution, so stay tuned. If you have any questions or feedback, leave me a comment below.


Comments, discussion & feedback.

Was this post helpful? Does it need work? Let me know below.