In my previous article, I discussed how I learned to create a decoupled WordPress powered Gatsby site using the Gatsby Source WPGraphQL plugin. The project was done following the ongoing developmental version of WPGraphQL and an excellent tutorial by Henrik Wirth. Although WPGraphQL was used in some production sites at that time, there were lot of iterations that introduced breaking changes. Since the release of WPGraphQL v1.0 last November, the plugin is stable and available via the WordPress plugin directory.
The WPGraphQL plugin can be used to create a site that uses WordPress for content management, but with a front-end that’s driven by Gatsby. We call this a “decoupled” or “headless” CMS because the site’s back-end and front-end are separate entities that still talk to one another via APIs where components on the front end consume data from the CMS.
The WPGraphQL plugin site has solid step-by-step documentation for getting started, and the release announcement post lists nine examples of production-level sites using the plugin.
In the true sense of a “decoupled” or “headless” site, WPGraphQL can be used to port WordPress data to other frameworks, like Next.js, Vue.js, among others. For the Gatsby framework, the Gatsby Source WordPress plugin is recommended, and it utilizes WPGraphQL to source data from WordPress.
Let’s set everything up together and tour the plugin.
Prerequisites
Table of Contents
In my previous article, we covered the prerequisites needed for setting up WordPress and Gatsby sites, and porting back-end WordPress data to a Gatsby-powered front-end site with site deployment. I’m skipping a lot of those details here because the fundamental concepts are the same for this article, except that WordPress data is fetched by the Gatsby Source WordPress plugin this time.
If you are new to Gatsby and just now jumping into Gatsby’s generated static site generator bandwagon, I’d suggest reading “An Honest Review of Gatsby” by React expert David Cramer and “Gatsby vs Next.js” by Jared Palmer. What we’re going to cover isn‘t for everyone, and these articles may be helpful to evaluate for yourself whether it’s the right technology for you and your project.
WPGraphQL, or GraphQL is the primary query language API used in Gatsby’s framework. There are frequent updates in GraphQL and that often requires expert knowledge and keeping an eye out for breaking changes. After all, GraphQL is designed by React experts for other React experts. That said, there’s some troubleshooting instructions and a WPGraphQL Slack where both the WPGraphQL and Gatsby Source WordPress plugin authors actively participate and help answer questions.
This article is not a step-by-step guide on how to use Gatsby Source WordPress Plugin. Again, that’s already available in Gatsby’s documentation. Conversely, if you happen to be an expert in React, JavaScript, Node.js or GraphQL, then what we cover here is probably stuff you already know. This article is an opinion piece based on my personal experience, which I hope is useful for the average WordPress user with basic working knowledge on the subject.
And, before we get started, it’s worth mentioning that the Gatsby Source WordPress plugin was completely rewritten in version 4 and uses WPGraphQL as its data source. The previous release, version 3, was built with REST API as its data source. Since the stable version of the plugin was recently released, the number of starter themes and demos that support it are limited.
First, we need WordPress
For this project, I set up a fresh WordPress site with Local by Flywheel that uses the default Twenty Twenty theme. I imported theme unit test data for pages and posts, as described in the WordPress Codex. While this was the baseline I was working with, this could have just as easily been an existing WordPress site that’s either on a remote server or a local install.
Now that we have an established baseline, we can log into the WordPress admin and install the WPGraphQL and WPGatsby plugins we need and activate them.
As we covered in the previous article, what this does is expose GraphQL and WPGraphiQL API in the WordPress admin, allowing the GraphiQL API to create a “playground” for testing GraphQL queries based on WordPress data.
Now we need a Gatsby front-end
Gatsby is well known for good documentation and solid starter templates. To create a new WordPress-powered site, Gatsby tutorials suggest that either using a starter or starting from scratch is just fine for what we’re doing.
Gatsby also offers a library of example websites for basic use cases that are built around a specific technology. There currently happens to be one that uses WordPress and one that uses WordPress with the Advanced Custom Fields plugin. Note that the example sites in the library still use gatsby-source-wordpress plugin 3 and have not yet updated to the version 4, as of this writing.
According to Gatsby tutorials, there are three options for creating a WordPress-powered Gatsby site. Let’s look at each one.
Option 1: Using the Gatsby starter
The docs have a step-by-step guide on how to set up a WordPress-Gatsby site, but here’s the gist.
Run the following in the command line to fetch the starter from GitHub repository and clone it into a my-wpstarter
project folder:
#! clone starter repo
gatsby new my-wpstarter https://github.com/gatsbyjs/gatsby-starter-wordpress-blog
Then, install the npm packages
#! npm
npm install #! or yarn
yarn install
Now that the starter is cloned, let’s open the gatsby-config.js
file in our code editor and update its URL option to fetch data from our WordPress endpoint (see above).
// gatsby-config.js
{ resolve: gatsby-source-wordpress, options: { // WordPress is the GraphQL url. url: process.env.WPGRAPHQL_URL || https://wpgatsbydemo.wpengine.com/graphql, },
},
Now, we’ll replace the starter’s data source endpoint URL with our own WordPress site URL:
// gatsby-config.js file
{ resolve: `gatsby-source-wordpress`, options: { url: `http://gatsbywpv4.local/graphql`, },
},
Let’s make sure we are in the my-wpstarter
project directory. From the project folder, we’ll run the gatsby develop
command to build our new Gatsby site from our WordPress data source endpoint. In the terminal we should be able see the gatsby-source-wordpress
plugin fetching data, including errors and successful site processes along the way.
If we see a success Building development bundle
message at the end, that means the Gatsby site build process is complete and the site can be viewed at http://localhost:8000
.
This is a bare-bone starter blog with basic files and a few components. It’s file structure is very similar to the gatsby-starter-blog, except this one has a templates folder that includes blog-post.js
and blog-post-achive.js
template files.
When we view the GraphiQL API explorer at http://localhost:8000/___graphql
we can see all of the data from WordPress exposed by WPGraphQL, as well as query and retrieve specific data right from the UI.
You got it! Gatsby assumes the rest is up to us to build, using Gatsby components that pull in WordPress data for the presentation.
Option 2: Building from scratch
Gatsby’s documentation offers a detailed step-by-step guide on how to create a new WordPress-Gatsby site from scratch using Gatsby’s default starter theme.
We’ll spin up a new project from the command line:
#! create a new Gatsby site
gatsby new wpgatsby-from-scratch-demo
This gets us a wpgatsby-from-scratch-demo
folder that includes the starter theme. From here, we’ll cd
into that folder and start developing:
cd wpgatsby-from-scratch-demo
gatsby develop
Now we can open up http://localhost:8000
in the browser and get the welcome page.
Now we are good to go to get start grabbing data from our WordPress site. Let’s install the Gatsby Source Plugin:
#! install with rpm
npm install gatsby-source-wordpress #! install with yarn
yarn add Gatsby-source-wordpress
If we check our browser now, you’ll noticed that nothing happens — we still get the same Gatsby welcome. To fetch our WordPress site data, we need to add the plugin to the gatsby-config.js
file. Open the file and insert the following:
// gatsby-config.js
module.exports = { siteMetadata: { // ... }, plugins: [ // Add Gatsby-source-wordpress plugin { resolve: `gatsby-source-wordpress`, options: { /* * The full URL of the WordPress site's GraphQL API. * Example : 'https://www.example-site.com/graphql' */ url: `http://gatsbywpv4.local/graphql`, }, }, // The following plugins are not required for gatsby-source-wordpress .... ],
}
Just like last time, we need to change the WordPress data endpoint source to the URL of our WordPress site. Let’s run gatsby develop
in our terminal to start things up.
However, when we open http://localhost:8000
in our browser, nothing seems to happen. We still see the same welcome screen. But if we examine GraphiQL in our browser (at http://localhost:8000/___graphql
) then we see all WordPress data exposed to our Gatsby site that we can query and display as we want.
Let’s test the following query I pulled straight from Gatsby’s tutorial, in the GraphiQL explorer:
query { allWpPost { nodes { id title excerpt slug date(formatString: "MMMM DD, YYYY") } }
}
When we run the above query, we will see the allWpPost.nodes
property value, with sub properties for id
, title
, excerpt
, and others.
Now, let’s open our src/components/pages/index.js
component file and replace the code with this:
// src/components/pages/index.js
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo" export default function Home({ data }) { return ( <Layout> <SEO title="home" /> <h1>My WordPress Blog</h1> <h4>Posts</h4> {data.allWpPost.nodes.map(node => ( <div> <p>{node.title}</p> <div dangerouslySetInnerHTML={{ __html: node.excerpt }} /> </div> ))} </Layout> )
} export const pageQuery = graphql` query { allWpPost(sort: { fields: [date] }) { nodes { title excerpt slug } } }
`
Save it, restart the server with gatsby develop
, and refresh the page. If the build was successful, then our site’s homepage should display a list of sorted blog posts from WordPress!
Following the tutorial, let’s create pages for each blog post and link the post title from the list to the post page. The process of creating pages using Markdown data is described in detail in Part 7 of the Gatsby’s foundational tutorial, which we will follow here as well.
As described in the tutorial, Gatsby uses createPages
API, or what it calls as its “workhorse” API, to programmatically create pages from data (from Markdown or WordPress). Unlike Markdown data, we don’t need to create a slug here because each WordPress post has its own unique slug which can be fetched from the WordPress data endpoint.
Creating pages for each post
Gatsby uses the gatsby-node.js
file, located at the root of our project, to programmatically create blog post. Let’s open the gatsby-node.js
file in our text editor add the following code from the tutorial.
// gatsby-node.js const path = require(`path`) exports.createPages = ({ graphql, actions }) => { const { createPage } = actions return graphql(` { allWpPost(sort: { fields: [date] }) { nodes { title excerpt content slug } } } `).then(result => { console.log(JSON.stringify(result, null, 4)) process.exit() })
}
As noted in the Gatsby Part 7 tutorial, the above code is the first part of creating our post pages from WordPress data source. Following the guide, let’s restart our server and develop our site with gatsby develop
.
We should see console.log
output in our terminal as pages being build). However, our homepage still looks the same. To create single posts, Gatsby requires templates to build pages, which we will create in next step.. That’s what we’ll do next.
Creating blog post templates
Let’s create a src/components/templates
folder in the src/
directory and create a blog-post.js
file by pasting the following code snippets from the tutorial:
// src/templates/blog-post.js
import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby" export default function BlogPost({ data }) { const post = data.allWpPost.nodes[0] console.log(post) return ( <Layout> <div> <h1>{post.title}</h1> <div dangerouslySetInnerHTML={{ __html: post.content }} /> </div> </Layout> )
}
export const query = graphql` query($slug: String!) { allWpPost(filter: { slug: { eq: $slug } }) { nodes { title content } } }
`
As explained in the tutorial, the above code snippets create a single post with React JSX and wraps post.title
and post.content
(lines 12-13) around the src/components/layout.js
components. At the bottom section of the file, a GraphQL query is added and calls a specific post based on the post slug variable $slug
. This variable is passed to the blog-post.js
template when the page is created in gatsby-node.js
.
Next we should also update lines 12-13 of our gatsby-node.js
file with the following code from the tutorial.
// gatsby-node.js
const path = require(`path`) exports.createPages = ({ graphql, actions }) => { const { createPage } = actions return graphql(` { allWpPost(sort: { fields: [date], order:DEC }) { nodes { title excerpt content slug } } } `).then(result => { result.data.allWpPost.nodes.forEach(node => { createPage({ path: node.slug, component: path.resolve(`./src/templates/blog-post.js`), context: { // This is the $slug variable passed to blog-post.js slug: node.slug, }, }) }) }) }
Let‘s stop and restart our local server with gatsby develop
and view the site. We won’t see our homepage with a list of blog post links. However, if we check with http://localhost:8000/abcdf
we should see the following 404 page with a list of individual pages and posts links.
If we check http://localhost:8000/hello-gatsby-world
, we should our “Hello Gatsby WordPress World” post in all its glory.
The next step is to link the post titles from the homepage to the actual posts.
Linking to posts from the homepage
Linking the work from the homepage to post pages is done by wrapping post titles in the index.js
file with Gatsby‘s Link
component. Let’s open the index.js
file that we created earlier and add the Link
component:
// src/components/pages/index.js
import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo" export default function Home({ data }) { return ( <Layout> <SEO title="home" /> {/* <h1>My WordPress Blog</h1> <h4>Posts</h4> */} {data.allWpPost.nodes.map(node => ( <div key={node.slug}> <Link to={node.slug}> <h2>{node.title}</h2> </Link> <div dangerouslySetInnerHTML={{ __html: node.excerpt }} /> </div> ))} </Layout> )
} export const pageQuery = graphql` query { allWpPost(sort: { fields: [date], order: DEC }) { nodes { title excerpt slug } } }
`
We imported the Link
component from Gatsby and then wrapped the post title with the Link
component and reference the slug of the post. Let’s clean up the code by commenting out the page title, changing the title element to <h2>
, and adding sorted posts order to DEC
in our graphql
query as well as the gatsby-node.js
file.
As we did earlier, let’s stop and restart the development server with gatsby develop
, and view our homepage at http://localhost:8000
. The post title should link to single post page.
This is as far as we’re going to take this second method. The rest of what we cover will describe how to fetch menu items and query other data types — like custom post types — and configure incremental build and previews etc.
You can apply the same procedure to calling and creating pages, custom post types, custom fields, taxonomies, and all the fun and flexible content WordPress is known for. This can be as simple or as complex as you would like it to be, so explore and have fun with it!
—Gatsby tutorial doc
Option 3: Using Gatsby’s WordPress Twenty Twenty Starter
Gatsby’s starter template for the default WordPress Twenty Twenty theme is created and maintained by Henrik Wirth, who also has an extremely detailed and thorough step-by-step guide that you might recall from my previous article. This starter, unlike the others, is actually updated to version 4 of the Gatsby Source Plugin and works out of the box after the initial WordPress setup described in the documentation. It maintains the same Twenty Twenty styling in the Gatsby front-end site, but has few limitations — including, comments, monthly archive pages, and tags — that are unsupported.
First let’s clone the starter in our twenty-twenty-starter
folder.
#! clone gatsby-starter-wordpress-twenty-twenty gatsby new twenty-twenty-starter https://github.com/henrikwirth/gatsby-starter-wordpress-twenty-twenty
Let’s cd
into that folder and then run gatsby develop
to spin up the site. It won’t work properly the first time because we have not changed our WPGRAPHQL_URL
value yet in the env.example
file. We need to rename the file from .env.example
to simply .env
, as suggested in the documentation.
After that, restart the development server with gatsby develop
. It should build the site successfully.
The menu may or may not appear depending on how the WordPress menu is named. The starter’s menu slug for querying menu items is primary
in Menu.js
(line 8). Because I had set my WordPress site up using main-menu
instead, I had to update the Menu.js
file accordingly.
Because the starter was tested with older versions of our tools , I decided bump up the plugins to the latest versions — WPGraphQL 1.2.6, WPGatsby 1.0.6, and Gatsby Source WordPress 4.0.1 — and it worked fine without any errors.
The Twenty Twenty starter follows the file structure of the Twenty Nineteen Gatsby theme, as well as Gatsby Starter WordPress Advanced. Henrik Wirth describes how WordPress data is ported to Gatsby in his step-by-step guide, as does Muhammad Muhsin in a tutorial. Otherwise, creating pages, page templates, porting menu items is exactly the same.
This starter uses the same CSS that the default WordPress Twenty Twenty theme does, and the same assets folder, including fonts, images, SVG files, and other files that are included in the default theme.
If you are happy with WordPress Twenty Twenty styling, then that’s it. Enjoy your new decoupled Gatsby site!
But let’s say we want to work with custom styles. The CSS files are imported from the assets
folder via the gatsby-browser.js
file.
Let’s modify the styles for the site’s header, footer, posts and pages. Gatsby provides different options to style its components and, in this project, I followed the CSS module for styling and modified CSS markup of the Twenty Twenty starter components accordingly.
We can start by creating a style folder at src/components/styles
and, inside it, a base
folder. Here’s the general file structure we’re aiming for:
#! partial structure of /style folder
src |--/components |--/styles |--main.css |--/base |--reset.css |--variables.css |--/scss |--header.module.css |--mainNav.module.css |--footer.module.css |--elements.module.css // and so on...
We want to style the site’s header and footer, so let’s open up the Header.js
and Footer.js
components in the starter and replace the code with the following:
// src/components/Header.js
import React from "react"
import { graphql, Link, useStaticQuery } from "gatsby"
import Menu from "./menu"
import style from "../styles/scss/header.module.css"
import logo from '../images/gatsby-icon.png' const Header = ( ) => { const { wp } = useStaticQuery(graphql` { wp { generalSettings { title description } } } `) return ( <header className={style.masthead}> <div className={style.masthead_info}> <Link to="/"> <img src={logo} alt="logo" width="100" height="100" display="inline-block" marginBottom= "0" className={style.site_logo} /> </Link> <div className={style.site_header} > <div className={style.site_title}> <Link to="/" dangerouslySetInnerHTML={{ __html: wp.generalSettings.title }} /> </div> <div className={style.site_description} dangerouslySetInnerHTML={{ __html: wp.generalSettings.description }} /></div> </div> <Menu /> </header> )
} export default Header
Similarly, the Footer.js
component was modified as follows:
// src/components/Footer.js
import React from "react" import style from "../styles/scss/footer.module.css" export default () => ( <footer className={style.colophon}> <p>© {new Date().getFullYear()} | This site is Powered by {' ' } <a href="https://www.gatsbyjs.org">GatsbyJS</a> {' and '} <a href="https://www.wordpress.org">WordPress</a></p> </footer>
)
Now, let’s restart our development server. We should see the following, including a new customized header and footer. I used the same style from Learning Gatsby which is an online course by Morten Rand-Hendriksen (I am a fan!).
You can grab the all the code I used over at GitHub.
What all this means for WordPress enthusiasts
There are many posts that compare the advantages and disadvantages of a decoupled WordPress and Jamstack site like the Gatsby examples we’ve covered. In my research, I realized that none of them are as exhaustive as what Chris already wrote in ”WordPress and Jamstack” where he compares everything, from performance and features, to the developer experience and build processes, and beyond.
I found the following articles draw some helpful conclusions on a variety of topics, including:
What’s the cost?
The general assumption is that Jamstack hosting is cheap, and cheaper than traditional LAMP stack hosting. But there’s actually quite a bit to consider and your actual costs might vary.
- “How to Run Your WordPress Site On Local, Gatsby and Netlify for FREE!” (Nate Fitch): Nate’s take is that a headless WordPress setup like this might be a good option if the project is a static blog or a site that doesn’t require any interactions. For example, It wouldn’t take too much work to get images hosted on Cloudinary, or another CDN, but it would for large, interactive sites.
- “WordPress and Jamstack” (Chris Coyier): There’s a specific section in here where Chris breaks down the pricing for different types of hosting for Jamstack sites and why a blanket statement like “Jamstack is cheaper” doesn’t fly because the actual cost depends on the site and its usage.
- “Choosing between Netlify, Vercel and Digital Ocean” by (Zell Liew): Zell discusses his experience choosing a hosting plan. His take: If you have a small project, go with Netlify; if you have a larger project, use Digital Ocean.
Why go static at all?
Considering all the things you get for “free” in WordPress — think comments, plugins, integrations, etc. — you might wonder if it’s even worth trading in a server-side setup for a client-side solution. In his “Static or Not?” post, Chris breaks down the reasons why you’d want to choose one over the other.
We get native commenting right out of the box with WordPress. Yet, support for comments on a static site is a bit of a juggernaut. In “JAMstack Comments” here on CSS-Tricks, the author explains how dynamic comments can be implemented in a static site, like Gatsby, using Netlify services. I briefly touched on this in my previous article.
What about SEO?
- “Gatsby SEO For WpGraphQL and Yoast” (Gatsby Community Plugin): The widely used Yoast SEO plugin for WordPress can be integrated into a Gatsby front-end using this plugin.
- “A primer on JavaScript SEO for WordPress” (Jono Alderson): This exhaustive guide includes a section on how to integrate Yoast SEO into a headless architecture and the implications of relying on JavaScript for SEO. The bottom line is that theme and plugin developers shouldn’t worry much about the changing landscape of JavaScript and SEO as long as they continue following best practices. At the same time, they should be aware of what’s changing and adapt accordingly.
How do things work together?
There are currently no Gatsby React templates that are geared toward non-developers but some agencies, like Gatsby WP Themes and the Themeforest marketplace, are beginning to fill the gap. For example, Gatsby WP Themes covers plugins for dynamic contents like MailChimp integration, using the Contact Form 7 plugin for forms, Yoast SEO, and more. Themeforest lists 30+ Gatsby templates, including the Gatsby – WordPress + eCommerce theme which gives you an idea of how far we can go with this sort of setup. Just remember: these are commercial sites, and much of what you’ll find has a cost attached to it.
My evolving personal take
If you recall, I ended my last article with a personal reflection on my journey to create a headless WordPress site that uses Gatsby as the front end. My initial take was less than a glowing review:
Based on my very limited experience, I think that currently available Gatsby WordPress themes are not ready for prime time use for users like me. Yeah, it is exciting to try something on the bleeding edge that’s clearly in the minds of many WordPress users and developers. At the same time, the constantly evolving work being done on the WordPress block editor, WPGraphQL and Gatsby Source WordPress plugins makes it difficult to predict where things are going and when it will settle into a state where it is safe to use in other contexts.
So, after all this my long journey to headless WordPress site, what is my take now? As an open-minded learner, my thoughts are still evolving. But I couldn’t agree more with what Chris says in his “Static or Not?” post:
It’s a perfectly acceptable and often smart choice to run a WordPress site. I think about it in terms of robustness and feature-readiness. Need e-commerce? It’s there. Need forms? There are great plugins. Need to augment how the CMS works? You have control over the types of content and what is in them. Need auth? That’s a core feature. Wish you had a great editing experience? Gutenberg is glorious.
I am a WordPress enthusiast and I love WordPress as a CMS. However, as a technological learning challenge, I have not given up yet to have a decoupled WordPress site as a personal project.
I must admit that learning to create a decoupled Gatsby site with WordPress has continued to be frustrating. I acknowledge that any modern technology stack is not “a cup of tea” for many WordPress users. Gatsby has steep learning curve as these stacks are targeted for experienced React and JavaScript developers.
Self-learning a new technology can be a frustrating experience. Learning Gatsby is especially frustrating if we (including yours truly) happen to lack experience with Node, React, JavaScript and, most importantly, GraphQL. My learning project sites would break because of some dependency and fixing it might take me several days of research. I sometimes wonder if the trouble is worth the outcome. Don’t get me wrong; my frustration is with my own lack of experience, not the frameworks themselves (because they are amazing).
Even experienced developers like David Cramer and Jared Palmer find using Gatsby and GraphQL frustrating and echo some of the same sentiments that we beginners face when using GraphQL. I couldn’t agree more with David who writes:
It’s a static website generator. It literally does not need GraphQL all over the place. While there are few instances in the real world where that is valuable, it shouldn’t require a GraphQL API to read objects that are already in memory.
GraphQL is an opinionated query language API and its specification changes frequently. Indeed, most of the discussion in the WPGraphQL Slack are related to queries.
While working on this project, I came cross the Frontity React Framework while reading an article on CSS-Tricks. It fetches all WordPress data with the REST API without writing a single query. That seems to be a better option, at least for my use case. Additionally, it appears to be a much simpler alternative. In my brief experience with it, I didn’t have to deal with any dependency or library issues at all. Frontity’s themes concept is so WordPress-y and provides excellent tutorials.
I am currently exploring whether the Frontity framework would be a better option for my decoupled project site and will share my experience in a future article.
Resources
Gatsby feels like it is targeted at experienced React and JavaScript developers, not for beginners like me! The gatsby-source-wordpress
and gatsby-source-wpgraphql
plugins do an excellent job of exposing WordPress data into Gatsby sites, but the rest is up to users to present the data on the front end using your framework of choice: React, Vue, Next, etc.
A lack of sound knowledge of React and JavaScript is the main hurdle for beginners. The Gatsby community fills a lot of these gaps, and there are a lot of resources available to keep learning and exploring.
Gatsby Conference 2021 talks
Two workshop talks from the recent 2021 Gatsby Conference were related to Gatsby WordPress sites. In one, Jason Bahl hosts a workshop that walks through how to create a Gatsby blog powered by WordPress data, including support the Yoast SEO plugin, and how to deploy the site to Gatsby Cloud.
There’s another workshop hosted by WP Engine’s Matt Landers where he demonstrates how to set things up using the Advanced Custom Fields plugin to create a team member page.
Both talks are good, especially if you learn better with hands-on experience. I also found this Matt Report podcast episode with Jason Bahl where Jason answers basic questions that are geared toward beginners.
Tutorial courses
Morten Rand-Hendriksen has an excellent course on LinkedIn Learning that uses the Gatsby Source WordPress plugin. If you are interested in more hands-on experience making a customized site that expands on the two Gatsby starters we covered, this course is great because in teaches how to create a complete working site, complete with a dropdown header navigation, footer menus, posts, pages, categories, tags, and page navigation.
The exercise files for the course are available in the GitHub LinkedIn Learning repository.
Gatsby starters
At the time I’m writing this, there are ten Gatsby starters for WordPress. As we mentioned earlier, only Gatsby Starter WordPress Twenty Twenty is based on the latest version of the Gatsby Source WordPress plugin; the rest are version 3.
Thanks for reading. I am always interested to know how fellow WordPress users who lack heavy technical experience like me are using this plugin. If you have any feedback, please feel free to post them in the comments.