Getting Started with Gatsby Source WordPress: Choose Your Own Adventure

Paul Scanlon
Paul Scanlon
April 8th, 2021

If you’re looking to get building with Gatsby and gatsby-source-wordpress, the official docs are the natural place to start. However, when I recently attempted to get up and running with Gatsby and WordPress to build my Shaping the Future of Headless WordPress demo, I encountered a missing piece or two. A few areas I felt weren’t quite as clear as they could have been, or that left me puzzled as to what I was supposed to do. 

My experience going down the rabbit hole with my own initial implementation of the newly GA gatsby-source-wordpressplugin inspired this follow-up post as more of a step-by-step “how to” approach. Just for fun, I’ve structured it as choose your own adventure in building your own headless WordPress site with Gatsby.

Everyone learns differently, I suppose. For some, the Gatsby docs may well provide everything you need. Jumping straight in to the Quick Start, you’ll be able to clone the Gatsby WordPress Starter, add a few config options and, bish-bash-bosh, a website appears. Awesome! Now let’s hit the foosball table!

But first, a question: Do you understand what you just did?

Your adventure begins here. 🚀

OK, the foosball tournament can wait a bit then while we take a walk together through the process of creating a new Gatsby + WordPress site, looking at each step along the way.

My approach: Typically, when working from installation docs, I like seeing shelland npmor yarn scripts, followed by code examples of where such things should live, plus a few handy words about what they actually do.

If you’re the same, you may prefer my slow and steady approach to getting started with Gatsby and WordPress. Let’s get started!

Before we go anywhere near Gatsby, let’s talk first about the WordPress side of things.

First, create a WordPress Instance

❓ If you already have a local or online instance of WordPress available (both will work) skip to 👉 WordPress plugins.

❓To create an online WordPress instance you might like to try The Single Shared Hosting option is pretty reasonable and will give you a WordPress site with domain name. After setting this up, you may then proceed to 👉 WordPress plugins.

❓Or, to create a local WordPress instance you might like to start here

❓ If you’d prefer to test the water first — as in, you do want to experiment with gatsby-source-wordpress but don’t have/don’t want to set up your own WordPress instance — you’re welcome to use my demo WordPress instance: If this is your choice, then from here skip ahead to 👉 JSON GraphQL

Next, install two WordPress plugins

To get things going, there are two official plugins that must be installed (and, even more crucially, activated) in the plugins sections of the WordPress user interface. Both are free and open-source WordPress plugins necessary for wiring up WordPress with Gatsby: 

  1. WPGraphQL — Provides an extendable GraphQL schema and API for any WordPress site.
  2. WPGatsby — Optimizes your WordPress site to work as a data source for Gatsby.

To install, look on the Dashboard on the left side of the WordPress UI. Click on ‘Plugins’ and then use the search to bring up WPGraphQL and WPGatsby from the vast galaxy of WordPress plugin choices. Click “install now” for both.

With both plugins installed and activated you should now see a GraphQL menu item appear in the sidebar (circled in red, in the image above). Click it and move to the next step. ➡️

Now set up GraphQL

Clicking on the GraphQL menu item will open this GraphQL Endpoint window:

In this window, look for the GraphiQL IDE menu item. GraphiQL is a tool that facilitates your data queries to GraphQL. Here you can use GraphiQL to query WordPress using GraphQL and preview the data returned by any valid query. 


The query names you see here aren’t the same as the query names you’ll be using in Gatsby, so by all means peruse it at your leisure. However, we won’t be using quite the same query names in the following steps. (This is because with Gatsby, in order to avoid query-clash between different platforms, any WordPress-specific query usually contains the letters “Wp” to identify it as WordPress related. Plural queries are prefixed with “all”. Don’t worry, I’ll show you the diff).

Here’s a side by side equivalent GraphQL query to show an example of one of the main differences: 


WordPress GraphQL

Gatsby GraphQL

  pages {
    nodes {
  allWpPage {
    nodes {


Back on the GraphQL page, below the GraphQL Endpoint item and input field at the very top, you’ll see a url for the new GraphQL endpoint. Make a note of this, since we will be using it in the next step ➡️.

Get your GraphQL Endpoint

(If you already happen to have your own GraphQL endpoint, go ahead and visit it. Or, feel free to have a look at mine

Copy/paste the endpoint url into your browser bar. If what you’re seeing in the browser looks a little perplexing, try installing this handy Chrome extension called JSON Formatter, and then refreshing the page.

You should now be looking at something like this 👇


This confirms that WPGraphQL and WPGatsby are working correctly. Move to the next step.  ➡️

Now, it’s time for Gatsby!

Setting up a minimal Gatsby site that can query and return WordPress data can be achieved by following this workflow, in four steps outlined below.

1. Core Dependencies

Type the following into your command line interface to install the core dependencies:

2. Gatsby Plugins 

Type the following into your command line interface to install the required Gatsby plugins:

You might not be using any images in your Gatsby site, but we need to install the gatsby-transformer-sharp and gatsby-plugin-sharp plugins no matter what — else, you’ll end up with errors in your terminal, and that’s an adventure nobody wants to choose. 🤷‍♂️

3. Gatsby Config

At the root of your project create a file called gatsby-config.js:

Now add the following code snippet, which ensures Gatsby uses the plugins you installed in step 2:


The url used by gatsby-source-wordpress is the same one you looked at earlier in the browser.

3. Scripts

Add the following code snippet to package.json:

4. Not Found Page

Create a new directory called src then create a directory called pages and finally create a new file called 404.js 👇

Whilst it’s not essential to create your own 404.js page, Gatsby will throw a 404 error in the browser console if one isn’t found. So might as well!


There’s no need to create any additional pages, not even an index.js. These will all come from WordPress!

Now, add the following code snippet to 404.js:

With dependencies installed, plugins configured, scripts added and a 404 not found page created — good work, by the way! Keep it up! — you can now move to the next step. ➡️

Start Server

To quickly check if everything is working correctly, spin up the Gatsby development server:


Visiting http://localhost:8000/ in your browser won’t show anything just yet besides the default Gatsby.js development 404 page. If you’d like to preview the ‘not found’ page you just created,  you can visit http://localhost:8000/404/.

A Warning 😬

Now is the time to check your terminal. If you see any spurious errors relating to createSchemaCustomization in your terminal, you might have a WordPress Plugin clash. One way to debug this is to logically disable existing WordPress plugins (note: in the WordPress UI, not plugins in the Gatsby build – just to be clear!) until the Gatsby build process completes successfully. 

Sadly, WordPress doesn’t provide Gatsby with any meaningful error codes. So, if you’re not in a position to disable existing WordPress plugins  — say,  for example, you’re working on a live WordPress instance where disabling plugins might break something else  on the live site — you might have a tough time debugging and your adventure may end here.

GraphiQL (again)

Before we go any further it’s worth investigating what should now be available in Gatsby’s GraphQL layer.

With the development server running, visit http://localhost:8000/__graphql and add the following query :

If all is well you should be seeing something that looks like this 👇

There’s a subtle but quite important different here, between allWpPage and allSitePage

allWpPage: This query returns all pages found in your WordPress site.

allSitePage: This query returns all pages found in your Gatsby site.

NOTE: At this current moment the pages exist in WordPress — but they don’t yet exist in Gatsby. To make this happen we will need to, err,  createPages. Let’s do it!

What’s a page?

This part can be a little confusing if you’re new to Gatsby. The key understanding here is, even though WordPress has returned pages, this doesn’t mean that Gatsby can automatically use them. 

To neatly resolve this disparity we’ll be using gatsby-node.js. This may seem a little daunting at first, but no worries — I’ll talk you through the nitty gritty.

You’re going to use the createPages API to create a page in your Gatsby site using data that is retrieved from your WordPress site. Once a page exists in Gatsbyland you can begin to populate it with data from WordPress, via the use of a page template. 

1. wp-page-template.js

Create a new directory in src called templates and then create a new file called wp-page-template.js

Something like this ought to do the trick 👇

Now add the following code snippet to wp-page-template.js:

<WpPageTemplate /> is a React component that will do the following:

  1. Query a single wpPage using graphql via an id made available by createPages (you’ll do this bit next) 
  2. Receive a data prop from the page query in step 1.
  3. Return HTML and data with JSX 

You can see from the destructured parameters that this component will reference and return both the title and content for each page queried by GraphQL.

Once wp-page-template.js has been created, you can now move to the next step. ➡️

2. createPages

Create a gatsby-node.js at the root of your project 👇

Now add the following code snippet:

You should see near the top you’re using the same allWpPage query you previewed earlier in GraphiQL. 

Using this query and then it’s possible to iterate over allWpPage.nodes returned by WordPress. Then, using Gatsby’s createPage action, you can use this data to create the “pages” for Gatsby to use in your site.

The createPage action injects an id , a uri and resolves to the <WpPageTemplate/> you created a minute ago.

The id is used by the  <WpPageTemplate/>  component to query data specific to that page and is how you’ll be able to return HTML and data via JSX. 😰

Once you’ve got all of that you can now move to the next step!  ➡️

Clean and Restart

Because we’ve tinkered with gatsby-node.js it might be advisable to stop the development server and run the code below before restarting the development server again.

Then spin up the development server again:

If all has gone as planned there’ll be a page available at each of the uri’s seen in the original allWpPage query. E.g you should see: 




Getting Around

Manually navigating to different urls won’t get you to the foosball table any time soon…But, using these last few tricks, I’ll show you how to add navigation to your Gatsby site


Create a new directory in src called layouts and then create a new file called page-layout.js

Something like this will do nicely 👇

Now add the following code snippet to page-layout.js:

Near the top you should see allWpMenu. This GraphQL query will retrieve all menu items from WordPress and return them in an array. You can then iterate over each menu item and use the labeland url to create a new <Link />.

The advantage of querying menu items directly from WordPress means you can hand over complete navigational control to the WordPress UI. If you no longer require a page to be displayed in the navigation of your Gatsby site you can remove it from the WordPress UI and, poof, the menu item will no longer be returned by this query. 

The mysterious children will be explained in the next step, shall we move on? ➡️


Create a gatsby-browser.js  file at the root of your project 👇

Now add the following code snippet to the file:

The above utilizes one of Gatsby’s browser APIs called wrapPageElement which, as the name suggests, wraps page elements. 

The element parameter can be considered as the “page” created earlier. By returning the element wrapped again by your new <PageLayout /> component, the element becomes the above mentioned “mysterious” children –  clear as mud? 🤯

FYI ☝️

gatsby-browser.js is a bit of a rascal. In the docs you’ll see examples that use the common Js / Node module.exportssyntax but — just so you know —you can also use ES6 syntax in here, too. ES6 is my preference.

With all of the above in place and the development server running, you should now be seeing a rather sorry looking <ul> containing links which, when clicked, will allow you to navigate around your Gatsby site.

The results should look something like this demo website, built from all the code we just worked through.  To find all the code in one convenient and organized location, visit the Choose Your Own Adventure GitHub repo.

And now you have a basic but functional Gatsby site with functioning WordPress! Hooray! 🎉

I hope you’ve enjoyed your little adventure, there are no further steps required, and all that’s left to say is TTFN !

Paul 🕺

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.