Shaping the Future of Headless WordPress: A Gatsby Demo

Paul Scanlon
Paul Scanlon
April 1st, 2021

Hi friends 👋 

I never thought I’d be saying these words, but…I’d like to introduce my new WordPress site!

Future Shapes is a gatsby-source-wordpress demo project designed to push on the boundaries of what’s possible when using Gatsby with headless WordPress (while having some fun along the way!). 

Why is this project surprising, coming from me? Well, like many developers, I am not a fan of classic WordPress. After some early formative experiences building WordPress sites for clients, I swore I’d never touch one again.

And then Gatsby announced a brand new WordPress source plugin and being a curious and open minded developer I thought it might be time to give it another go. 

After all, using WordPress with Gatsby means I can just treat it like any other headless CMS, right? Now WordPress is no longer my worst nightmare, but simply a data source. So I decided to put gatsby-source-wordpress  through its paces. 🕺

The “Future Shapes” idea came from the paradigm shift made possible by WPGraphQL: an effective route to using WordPress simply as a data source. Building sites that keep the content/marketing team happy, yet with all the benefits of a Gatsby site and none of the drawbacks of traditional WordPress — to me, it feels like we are changing the future shape of how developers and marketers can work together, independently and harmoniously.

Why WordPress?

Before I dive in I’d like to address the elephant in the room: Why, as a developer, would you willingly choose WordPress as a headless CMS? Especially given the abundance of alternatives, many of them purpose-built to be headless from the start. WordPress, created in 2003 before anyone really knew what “headless” meant, was most definitely not.

I posed this question to a number of my React-aware developer chums and all pretty much responded with strongly worded but eloquently constructed paragraphs containing multiple expletives.

I then realised I was asking the wrong people. 

Had I proposed the same question to content creators, marketers or clients (the decision makers) I’m pretty sure the response would have contained some very good reasons why people on the content side prefer WordPress. Not to mention fewer profanities.

Some real-world, non-technical reasons why WordPress is a favourable CMS choice:

  1. Content creators, marketers and clients alike have been using WordPress for many years, and they like it
  2. Content creators create content. If they have a tool they like and are comfortable with, why would they want to change that? (Also: It’s not their job to learn new tech in quite the same way as it is ours as developers). 
  3. It’s a big ask for any company to invest time and money migrating it away from WordPress primarily to keep the dev team happy.

But instead of focusing on the things we can’t change let’s start thinking about the things we can.

Enter Gatsby

Gatsby, as you may already know, is a great way to build using cutting edge React technology. But the framework’s true superpower is how Gatsby remains agnostic with regard to almost everything else you may need. Gatsby’s plugin eco-system is a treasure chest of brilliant and incrementally adoptable solutions to almost every problem you’ll face.

Plugins are also how we get Gatsby and headless WordPress playing nicely together, so you can keep the familiar WordPress interface for collaborating on content creation, editing and updating but ditch the cumbersome WordPress theme layer for the faster and more efficient Gatsby architecture powering how your content gets built, deployed, and presented. 

(And the Marketing team will never know the difference 🕺).

WPGraphQL is what makes this all possible. WPGraphQL is a WordPress plugin that adds a GraphQL API to your WordPress site. (GraphQL being a query language for fetching information from an API).  Gatsby incubated WPGraphQL as an open source project and today offers quite an attractive solution to developing WordPress sites using the new general release source plugin gatsby-source-wordpress.

In addition to WPGraphQL there are some equally powerful WordPress plugins that provide more control over how data is stored and then retrieved which opens up even more possibilities when working with Gatsby. 

 Let’s meet the major players.

Two official WordPress plugins that have been around for awhile:

Their corresponding WPGraphQL plugins:

Using a combination of these plugins it’s possible to expose editable fields to the content creators in the familiar WordPress UI — and then consume it via GraphQL for Gatsby to display in new and imaginative ways. So how does this work in an actual site?

Testing 1, 2 …

To really test this out I devised a few common and some less uncommon examples that I know are possible with purpose built headless CMSs — but would it / could it be possible with WordPress? Let’s find out.

First, here’s an example of how an Advanced Custom Field (ACF) can be used in WordPress. The  Future Shapes demo site shows how decoupling the data from the page itself lets us display a “featured” YouTube promo on the Home page, and then randomly select from “non featured” YouTube promos to be displayed on any subsequent pages or posts.

This is how I query the data in GraphQL (check out the full source code):

A second example of how I’ve used an Advanced Custom Field (ACF) is with creating the posts themselves. For the Future Shapes project, each post is about a type of shape; I wondered if it would be possible to use WordPress to save an Svg path, query it using GraphQL, and then pass the path on to my own React Svg component

In this example I’ve again used an Advanced Custom Field (ACF) and combined it with Custom Post Types to attach the ACF for the Svg Attributes to each of the “posts” in WordPress. I also used the same approach with the Thumbnail image.

Here’s an example of what a “post” looks like in WordPress with both Svg Attributes and the Thumbnail Image attached via Custom Post Types:



This is how to query the data in GraphQL (source code):

There’s a couple of other tricks in the posts query too.

Firstly, the Featured Image that is uploaded to WordPress is sourced and then processed by Gatsby’s new gatsby-plugin-image. (There are many advantages to sourcing images in this way so here’s Laurie Barth presenting a superb demo at this year’s GatsbyConf). 

Secondly, I wanted to do something a little different with the tags. Tags are usually assigned to posts to group items together so users can explore related content. Most of the time in a WordPress site the tags will be listed next to one another on the page, however, in the case of my shapes I wondered if i could do something a little more interesting. 

If we enter into JavaScript land anything is possible, right? By querying the tags in GraphQL I can hand them over to JavaScript and in my Gatsby demo site the tag name is actually a CSS transform property. E.g scaleX, scaleY and rotate. These “tags” are then applied to the Svg via CSS and the values are made interactive via the use of an HTML <input type="range" /> allowing users to not only see and read the tags but interact with them too. (If a tag isn’t present in the post, the range slider becomes disabled).

The Big Experiment

The proof of concept testing was successful and I was feeling quite confident that WordPress can, in fact, do all the things its newer, purpose-built headless CMS friends can do. Now it was time to really push the limits. I came up with a big experiment:

Could I query WordPress and return svg paths and absolute urls for audio files I’d uploaded to the media section of WordPress — and then use them to create a Bauhaus inspired interactive shape and sound mega mix????

TLDR; yes!

Behold, The Experiment! Visitors to can press any key, or click any shape, to randomly spin, flip and swap different pieces — with random sound effects generated for each interaction. How does one achieve such madness, you ask? That is an excellent question, and one that kept me up late several nights running.

First up I needed to query all the svg paths. This was achieved using the following GraphQL query (full source code).

Next I query all the mpegs using a similar query (source code here):

A bit of trouble in the laboratory

At this point I did run into a little issue with querying the mpegs.

I planned to use the mediaItemUrl as a url for JavaScript’s Audio constructor — e.g. new Audio(mediaItemUrl).

In theory this is a totally legit usage. However, as far as gatsby-source-wordpress and WPGraphQL are concerned, I’m not actually using any mpegs!

I didn’t want a page with an HTML <audio>`<source src="..." type="audio/mpeg" /></audio> for each and every mpeg I planned to use — kind of defeats the whole purpose here, honestly. But, unless I did, GraphQL wouldn’t query the media items correctly. 

In theory, gatsby-source-wordpress is doing what it’s supposed to do by only querying media you’re actually using. But, I was using Audio! I just wasn’t using Audio the way GraphQL expects it to be used… the perils of thinking outside the box I suppose 🤷‍♂️

Also, confusingly, gatsby-source-wordpress queries these “unused” media items fine in development but when I pushed to production I found that the query for the mpegs returned null. No errors, or indication as to why, but, tucked deep inside the docs, I came across this:

Only media items that are referenced by at least 1 other node are sourced. For example if you have image a.jpeg and b.jpeg and in the Hello World post, you add a.jpeg as a featured image (or other field) but b.jpeg is not included anywhere, only a.jpeg will be sourced by Gatsby.

To combat this I made a special “hidden” page. This tricks Gatsby into thinking the mpegs are being used in a “page” even though I am not using this page in my demo site…So I win that one 😏

Now that I had query-able urls for each mpeg working in production I could go about my business and create my experiment. I’ve said this before and I’ll say it again: 

If you can do it with React, you can do it with Gatsby.

The src for the experiment can be found here and the src for the sound-tile can be found here

Now, about pages.

It is of course entirely possible that your requirements will be much more page related than anything I was doing above. Even in the headless future, almost every site should likely include an About page, right?

Here’s what that looks like in WordPress:

And as you might expect it looks very similar in the Gatsby demo site:

Appearances can be deceiving! The bit I’d like to draw your attention to is the “side by side” lists. 

Placing things side by side isn’t a job for HTML — it’s CSS that does this. Does gatsby-source-wordpress query CSS? Um, no, it does not 😬.

This is a problem. Gutenberg, the WordPress UI,  is responsible for arrangeing and styling HTML content in the WordPress editor — but in Gatsby we’re only querying the data.

To show you what I mean here’s the query that handles getting the page “content”. (i’ve removed a large part of the query for brevity)

To render the “content”  in React I have to pass the “content” node onto a div using dangerouslySetInnerHTML.

(Note: I’m using dangerouslySetInnerHTML here for demonstration purposes. If you decide to try this at home you’d probably want to use html-react-parser.)

The reason this React method is dangerous is because in our code we have no way to know what the “content” will actually be. We know it’ll be HTML but — as you’ll notice from the code below — we also end up with a few Gutenberg specific CSS class names, likeclass="wp-block-columns":

To achieve the layout the content creator choses in WordPress, we need to make sure we can handle the same CSS rules in our Gatsby build.

It took me a long time to find this but… it is possible to install all the Gutenberg CSS via a node module. (I am very proud of this discovery 😊).

To the best of my knowledge the following are the two node modules you’ll need to have installed and imported into your Gatsby project

I’ve imported these in my main page template so the Gutenberg CSS is included in my Gatsby build. You can see the src for my page template here.

If the Gutenberg CSS is included in your Gatsby build, in theory anything a content creator does using the Gutenberg blocks will be styled the same way in your Gatsby build…Phew!

That just about wraps up my tinkering and I have to admit using WordPress in headless mode is actually pretty cool. It’s truly quite mind boggling that all of the above is now possible with WordPress, and personally I think Jason, Tyler and the rest of the Gatsby team have done an outstanding job in taming the beast.

I’m not sure what’s next for gatsby-source-wordpress and WPGraphQL but it has made me think: could gatsby-source-wordpress help, ahem, shape the future of WordPress? 

I really think it can!

See you around friends! 🕺


Paul Scanlon
Written by
Paul Scanlon

Jamstack Developer based in Worthing, UK. After all is said and done, structure + order = fun.

Follow Paul Scanlon on Twitter

Talk to our team of Gatsby Experts to supercharge your website performance.