WordPress
WordPress claims to be, “the world’s most popular website builder” based on the statistic that 38% of the web is built on WordPress. Despite the classification as a ‘website builder’, the most renowned feature of WordPress is the ease of content editing that it provides. Technical and non-technical users can quickly add and edit content, which gets their information to the world faster. WordPress helps people create websites, but it’s a content management system (CMS).
The WordPress CMS was introduced in 2003 to support blogging. It is written using the PHP programming language and has many plugins that users can attach to their site for added functionality.
WordPress has faced many critiques over the years, concerning:
- security threats
- the use of PHP
- speed
Over the years, new programming languages, web frameworks, and content management systems have emerged that seek to challenge the power of WordPress. Despite the newcomers, WordPress remains a contender whenever someone is looking to create a website. Furthermore, many users are comfortable with WordPress’s CMS.
In this article, we are going to talk about how we can combine the content management system power of WordPress with:
- ReactJS for building user-interfaces
- GatsbyJS for fast-loading HTML
- GraphQL for querying data within Gatsby
This approach allows developers to mitigate all three of the aforementioned criticisms with new technology.
React
ReactJS is a Javascript web framework for building user-interfaces. Stack Overflow, an extremely popular forum for asking and answering programming questions, released their developer survey for the year 2020. They surveyed over 65,000 developers with one section covering the Most Loved, Dreaded, and Wanted Web Frameworks. ReactJS was ‘loved’ by 68.9% of developers. The percentage is developers, “who are developing with the language or technology and have expressed interest in continuing to develop with it.” This earned ReactJS a second-place finish behind ASP.NET Core (70.7%).
ReactJS was revolutionary in its ability to create a seemingly fast user experience by combining features like components, state, props, JSX, and a virtual document object model (DOM). To learn more about ReactJS, you can:
Gatsby
Gatsby is a React-based open source framework for creating websites and apps. Build anything you can imagine with over 2000 plugins and performance, scalability, and security built-in by default
In the same survey mentioned above, Gatsby placed fifth—being ‘loved’ by 60% of respondents—despite being new to the survey. One way to interpret that is: GatsbyJS is on the rise.
Gatsby is a static site generator. That means that it compiles React code and data into static assets (HTML, images, CSS). These assets make up the web application and are distributed globally with a service like Netlify.
Gatsby, like WordPress, has a plugin architecture that allows users to integrate different data sources into their sites. It’s become part of the JAMstack, short for a technology stack utilizing Javascript, APIs, and Markdown. However, that’s not the only way that it can be tooled.
Plugins, for Gatsby, let the user pull data from sites like Shopify, Stripe, and WordPress. This means that sites can break away from monolithic website structures (i.e Shopify, WordPress) and build custom sites with React. Users query data from sources using GraphQL.
GraphQL
GraphQL lets developers grab exactly the data they need from a single API endpoint using a query string. In a REST API, you may need to fetch a user’s name. However, to get the name, you have to fetch ALL the user’s data. As a consequence, you have to add more code to your program to process the payload to only get the name property. With GraphQL, you can query for the name property and pinpoint your API calls for the exact data you need.
To learn about GraphQL, and why it’s becoming so popular, you can view the following resources:
We can combine two WordPress plugins with one Gatsby plugin to open up a GraphQL API with our WordPress site. Then, we can query data from that site and put it into our ReactJS app. The next part of the article is a tutorial on how we can combine these technologies to take advantage of their features. In this way, non-technical users can still use the CMS that they love, and developers can take control by using a modern web framework like React!
Create an App Using WordPress and React
This tutorial is based on a tutorial by Tyler Barnes, who is a contributor to the gatsby-source-wordpress-experimental and co-creator of the WordPress plugin WP Gatsby.
Prerequisites
- Knowledge of how to open and use a command-line tool (i.e BASH, PowerShell)
- Basic understanding of:
- ReactJS
- GraphQL
- Install NodeJS
- Internet connection (for downloading development software)
1. Setup the Project
Setup Local WordPress Hosting
We are going to use Local to develop a WordPress site locally. Visit https://localwp.com/ and click the Download button.
Select your operating system and provide the required information. Next, open up the downloaded program and run it to install. Accept the terms of service.
Then, open up the application and create a new site named wordpress-react.
In the next section, Setup Environment, select the Custom tab. Choose the latest PHP version, Apache web server, and the latest MySQL option.
Finally, create a WordPress username and password that will be used to sign in to the local website. Click Add Site, and wait for the service to build.
Take note of the Site Domain. This is the URL for your WordPress site that is running locally. We will be using this later to set up the GraphQL endpoint.
You should now be able to visit your WordPress site running locally at http://wordpressreact.local/
.
Next, we need to create a new local Gatsby site.
Setup New Gatsby Project
Open up a command-line tool and install the Gatsby CLI.
npm install -g gatsby-cli
Then, create a new site.
gatsby new wordpress-react
Change directories into the newly created folder wordpress-react
.
cd wordpress-react
Start the new Gatsby site by running gatsby develop
. The site will build, and then you can visit the site at http://localhost:8000/
.
We now have a local WordPress site running at http://wordpressreact.local
and a local Gatsby site running at http://localhost:8000
.
In the next section, we are going to download and configure the GraphQL API for both sites.
2. Create GraphQL API with WordPress and Gatsby
Configure Gatsby Plugin
Next, download the WordPress plugin for Gatsby. Make sure that you are still in the root project folder for the Gatsby site.
npm install gatsby-source-wordpress-experimental
Open up your IDE or text editor in the main wordpress-react
folder. As a side note, I am using Visual Studio Code.
Paste the following code into gatsby-config.js
, replacing any code that is currently in the file.
module.exports = { siteMetadata: { title: `Wordpress + React Tutorial`, description: `Using WordPress as CMS with React`, author: `@gatsbyjs`, }, plugins: [ { resolve: `gatsby-source-wordpress-experimental`, options: { url: `http://wordpressreact.local/graphql`, }, }, `gatsby-plugin-react-helmet`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images`, }, }, `gatsby-transformer-sharp`, `gatsby-plugin-sharp`, { resolve: `gatsby-plugin-manifest`, options: { name: `gatsby-starter-default`, short_name: `starter`, start_url: `/`, background_color: `#663399`, theme_color: `#663399`, display: `minimal-ui`, icon: `src/images/gatsby-icon.png`, }, }, ], }
Most of the code is generic starter code. The important part is configuring the gatsby-source-wordpress-experimental
plugin. Here, we provided the URL to our site’s GraphQL endpoint. We have to restart the development server to see any changes that we make in the gatsby-config.js
or gatsby-node.js
.
However, the URL http://wordpressreact.local/graphql
doesn’t exist so the site will fail to build.
Upload and Configure WordPress Plugins
Open up a browser and navigate to https://github.com/gatsbyjs/wp-gatsby. Click the green Code button to open up a dropdown. Then select Download Zip.
Next, navigate to https://github.com/wp-graphql/wp-graphql and download the zip file for that plugin as well.
These are the two plugins that we need to install on our WordPress site to use Gatsby and GraphQL.
Open up http://wordpressreact.local/wp-admin and sign-in to your site with the username and password you entered when creating the site with Local.
Click on Plugins in the side navigation. Then click the Add New button at the top.
Upload and activate both plugins to the WordPress site that were just downloaded from Github. This is done by clicking the Upload Plugin button at the top of the Add Plugins page.
After activating the plugins, restart the Gatsby development server.
Nothing should look different on the site, but it should still build and be accessible from the local URL.
3. Pull Data from WordPress into Gatsby Site
We still have two different sites running. We want to be able to get data from the WordPress site into the Gatsby project. To do this, we are going to insert GraphQL queries into the Gatsby project that pulls from our WordPress site.
First, open up the file src/pages/index.js
.
Remove all the code in the <Layout>
component except for the <SEO />
component. Then, add the following code beneath the <SEO />
component.
.... <h1>My WordPress Blog</h1> <h4>Posts</h4> <section className="posts-container"> {data.allWpPost.nodes.map((post) => ( <div className="post-preview" key={post.slug}> <Link to={post.slug}> {post.title} </Link> </div> ))} </section> ....
The index.js
file is the home page for the application. We added a section that will loop over data—passed in by the props—holding the slug and title for the blog posts from WordPress. However, we need to add the page query so Gatsby can fetch this data for the component.
At the bottom of index.js
, add:
... export const pageQuery = graphql` query { allWpPost(sort: { fields: [date] }) { nodes { title slug } } } `
Finally, as a parameter to the IndexPage
component add { data }
. This deconstructs the props value data
that is injected into the component by Gatsby. The data
property holds the data that is fetched by the GraphQL query.
The code inside index.js
will now be:
import React from "react" import { Link } from "gatsby" import Layout from "../components/layout" import Image from "../components/image" import SEO from "../components/seo" const IndexPage = ({ data }) => ( <Layout> <SEO title="Home" /> <h1>My WordPress Blog</h1> <h4>Posts</h4> <section className="posts-container"> {data.allWpPost.nodes.map((post) => ( <div className="post-preview" key={post.slug}> <Link to={post.slug}> {post.title} </Link> </div> ))} </section> </Layout> ) export default IndexPage export const pageQuery = graphql` query { allWpPost(sort: { fields: [date] }) { nodes { title slug } } } `
The development server will restart and the app will pull data for the only blog post currently on the WordPress site (Hello world!).
Now, if you were to log in to the WordPress site, edit the title, and republish the post, the title would update on the Gatsby site. Unfortunately, the actual page for the blog post doesn’t exist, so clicking the link leads to a 404 page.
3. Create Blog Post Pages
Gatsby can generate many pages from queried data. This is done in the gatsby-node.js
file.
Open the gatsby-node.js
file and add the code,
const path = require(`path`) exports.createPages = ({ graphql, actions }) => { const { createPage } = actions return graphql(` { allWpPost(sort: { fields: [date] }) { 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: { slug: node.slug, }, }) }) }) }
The above code uses Gatsby’s createPage
function. This function takes in an object that configures the page to be created. The path parameter is the path that the page is found at (i.e /hello-world
). The component parameter takes the path to the component that is responsible for rendering the data. This component doesn’t exist yet. The context object is a way for us to pass variables to the component to be used in the query or the component.
At this point, you may be wondering where these queries are coming from. Open up a browser to http://localhost:8000/__graphql.
This is the GraphQL explorer that helps us build and test queries from the schemas that the GraphQL plugin was able to find. Enter the following query into the middle panel.
query MyQuery { allWpPost(sort: { fields: [date] }) { nodes { title excerpt content slug } } }
Press the play button to run the query. You should see the information for the one blog post that we have on our WordPress blog.
We can use this Gatsby feature to build and test queries that select only the data we need from our WordPress GraphQL API.
To create the blog pages, we need to create the component at src/templates/blog-post.js
.
Add the folder templates/
underneath the src
directory. Create the file blog-post.js
and add the code:
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 } } } `
This code creates a component that will display the post content. The GraphQL query uses the context variable slug
that was passed on the context object in gatsby-node.js
. We are then able to query for the blog post’s data based on its slug.
Restart the development server to build the blog post pages.
Now, when you click on the link to the blog post “Hello world!”, you are taken to the blog post.
4. Add Another Blog Post
Log in to your WordPress site (if you are not logged in already) and click on Posts in the side navigation. Then click the button Add New.
- Give the post the title “Check this out!”
- Add a featured image
- Add an excerpt
Publish the post.
Now, we have two posts displaying on the home page. Before we add new data to the query, add a featured image and excerpt to the Hello world! post and republish.
Back in src/templates/index.js
, add the excerpt and featured image to the query at the bottom of the page.
export const pageQuery = graphql` query { allWpPost(sort: { fields: [date] }) { nodes { title excerpt slug featuredImage { node { localFile { childImageSharp { fluid { src aspectRatio base64 originalImg originalName presentationHeight presentationWidth sizes srcSet srcSetWebp srcWebp } } } } } } } } `
Next, add a Gatsby image component to display the featured image of each blog post and new div
to display the excerpt.
.... <Layout> <SEO title="Home" /> <h1>My WordPress Blog</h1> <h4>Posts</h4> <section className="posts-container"> {data.allWpPost.nodes.map((post) => ( <div className="post-preview" key={post.slug}> <Image className="featured-image" fluid={post.featuredImage.node.localFile.childImageSharp.fluid} /> // new <Link to={post.slug}> {post.title} </Link> <div className='excerpt' dangerouslySetInnerHTML={{ __html: post.excerpt }} /> // new </div> ))} </section> </Layout> ....
Finally, at the top of the file, change the Image
import from import Image from '../components/image'
to import Image from 'gatsby-image'
.
This code renders the featured image and excerpt for each post. However, it needs some CSS.
5. Add Styling
Open up src/components/header.js
and change the <header>
background style property from `rebeccapurple`
to `black`
.
Then, in the file layout.css
, add the following code at the bottom above the media query.
.posts-container { display: flex; justify-content: space-around; } .excerpt { margin: 0.5rem; padding: 0.5rem; } .featured-image { height: 200px; margin-bottom: 1rem; } body { background: #EEE; } h1 { font-family: monospace; } a { padding: 0.2rem 0.5rem; border: 2px solid black; color: black; text-decoration: none; box-shadow: 0px 0px 11px -4px black; margin: 1rem; } .post-preview { box-shadow: 0 0 20px 10px #CCC; margin: 1rem; padding: 1rem; }
Save the file and refresh the app if needed. Your app should now look a little better!
Conclusion
One hurdle the get over with this technology line-up is the ability to preview content and accurately adjust CSS appearance. You can set up a preview by connecting the deployed site to Gatsby Cloud. You can follow this link to learn more about previews.
As for the CSS and appearance, there is more work that needs to be done to align the theme (and content editing) to the style sheets that are in play in the Gatsby project. This requires better knowledge of WordPress but is beyond the scope of this article. Furthermore, many data parameters can be pulled from the WordPress site and it’s worth exploring the options in the GraphiQL Explorer (http://localhost:__graphql).
GraphQL APIs can be tricky as a beginner. I recommend the following resources for further reading:
Thanks for reading!
Denny Smith says
Very useful & informative article! Thanks for sharing! WordPress and React is a powerful way to build web applications!
Jarrett Retz says
You are welcome Denny, thank you for reading and sharing your thoughts!