{"id":338051,"date":"2021-04-23T07:03:18","date_gmt":"2021-04-23T14:03:18","guid":{"rendered":"https:\/\/css-tricks.com\/?p=338051"},"modified":"2021-04-26T15:56:15","modified_gmt":"2021-04-26T22:56:15","slug":"using-new-gatsby-source-wordpress-plugin","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/using-new-gatsby-source-wordpress-plugin\/","title":{"rendered":"Using New Gatsby Source WordPress Plugin"},"content":{"rendered":"\n

In my previous<\/a> article, I discussed how I learned to create a decoupled WordPress powered Gatsby site using the Gatsby Source WPGraphQL<\/a> plugin. The project was done following the ongoing developmental version of WPGraphQL and an excellent tutorial<\/a> by Henrik Wirth<\/a>. 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<\/a> last November, the plugin is stable and available<\/a> via the WordPress plugin directory.<\/p>\n\n\n\n

The WPGraphQL plugin can be used to create a site that uses WordPress for content management, but with a front-end that\u2019s driven by Gatsby. We call this a \u201cdecoupled\u201d or \u201cheadless\u201d CMS because the site\u2019s 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.<\/p>\n\n\n\n

The WPGraphQL plugin site has solid step-by-step documentation<\/a> for getting started, and the release announcement post<\/a> lists nine examples of production-level sites using the plugin.<\/p>\n\n\n\n\n\n\n\n

\"Selected
The Denver Post, The Twin Cities Pioneer Press, The San Jose Mercury News, and Credit Karma have a decoupled WordPress site with WPGraphQL.<\/figcaption><\/figure>\n\n\n\n

In the true sense of a \u201cdecoupled\u201d or \u201cheadless\u201d site, WPGraphQL can be used to port WordPress data to other frameworks, like Next.js<\/a>, Vue.js<\/a>, among others. For the Gatsby framework, the Gatsby Source WordPress<\/a> plugin is recommended, and it utilizes WPGraphQL<\/a> to source data from WordPress.<\/p>\n\n\n\n

Let\u2019s set everything up together and tour the plugin.<\/p>\n\n\n

Prerequisites<\/h3>\n\n\n

In my previous article<\/a>, 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\u2019m 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<\/a> plugin this time.<\/p>\n\n\n\n

If you are new to Gatsby and just now jumping into Gatsby\u2019s generated static site generator bandwagon, I\u2019d suggest reading \u201cAn Honest Review of Gatsby\u201d<\/a> by React expert David Cramer and \u201cGatsby vs Next.js\u201d<\/a> by Jared Palmer. What we\u2019re going to cover isn\u2018t for everyone, and these articles may be helpful to evaluate for yourself whether it\u2019s the right technology for you and your project.<\/p>\n\n\n\n

WPGraphQL, or GraphQL is the primary query language API used in Gatsby\u2019s framework<\/a>. 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\u2019s some troubleshooting instructions<\/a> and a WPGraphQL Slack<\/a> where both the WPGraphQL and Gatsby Source WordPress plugin<\/a> authors actively participate and help answer questions.<\/p>\n\n\n\n

This article is not a step-by-step guide on how to use Gatsby Source WordPress Plugin. Again, that\u2019s already available in Gatsby\u2019s documentation<\/a>. Conversely, if you happen to be an expert in React<\/a>, JavaScript, Node.js<\/a> or GraphQL<\/a>, 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.<\/p>\n\n\n\n

And, before we get started, it\u2019s worth mentioning that the Gatsby Source WordPress<\/a> 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.<\/p>\n\n\n

First, we need WordPress<\/h3>\n\n\n

For this project, I set up a fresh WordPress site with Local by Flywheel<\/a> that uses the default Twenty Twenty theme<\/a>. I imported theme unit test data<\/a> for pages and posts, as described in the WordPress Codex<\/a>. While this was the baseline I was working with, this could have just as easily been an existing WordPress site that\u2019s either on a remote server or a local install.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

Now that we have an established baseline, we can log into the WordPress admin and install the WPGraphQL<\/a> and WPGatsby<\/a> plugins we need and activate them.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

As we covered in the previous article<\/a>, what this does is expose GraphQL and WPGraphiQL<\/a> API in the WordPress admin, allowing the GraphiQL<\/a> API to create a \u201cplayground\u201d for testing GraphQL queries based on WordPress data.<\/p>\n\n\n\n

\"Screenshot
The GraphiQL screen provides three panels: one to navigate between different objects (left), one to query data (center), and one to visualize the returned data (right).<\/figcaption><\/figure>\n\n\n

Now we need a Gatsby front-end<\/h3>\n\n\n

Gatsby is well known for good documentation<\/a> and solid starter templates<\/a>. To create a new WordPress-powered site, Gatsby tutorials suggest that either using a starter<\/a> or starting from scratch<\/a> is just fine for what we\u2019re doing.<\/p>\n\n\n\n

Gatsby also offers a library of example websites<\/a> for basic use cases that are built around a specific technology. There currently happens to be one that uses WordPress<\/a> and one that uses WordPress with the Advanced Custom Fields plugin<\/a>. Note that the example sites in the library still use gatsby-source-wordpress plugin 3<\/a> and have not yet updated to the version 4, as of this writing.<\/p>\n\n\n\n

According to Gatsby tutorials<\/a>, there are three options for creating a WordPress-powered Gatsby site. Let\u2019s look at each one.<\/p>\n\n\n

Option 1: Using the Gatsby starter<\/h3>\n\n\n

The docs<\/a> have a step-by-step guide on how to set up a WordPress-Gatsby site, but here\u2019s the gist.<\/p>\n\n\n\n

Run the following in the command line to fetch the starter from GitHub repository<\/a> and clone it into a my-wpstarter<\/code> project folder:<\/p>\n\n\n\n

#! clone starter repo\ngatsby new my-wpstarter https:\/\/github.com\/gatsbyjs\/gatsby-starter-wordpress-blog <\/code><\/pre>\n\n\n\n

Then, install the npm packages<\/p>\n\n\n\n

#! npm\nnpm install\n\n#! or yarn\nyarn install <\/code><\/pre>\n\n\n\n

Now that the starter is cloned, let\u2019s open the gatsby-config.js<\/code> file in our code editor and update its URL option to fetch data from our WordPress endpoint (see above).<\/p>\n\n\n\n

\/\/ gatsby-config.js\n{\n  resolve: gatsby-source-wordpress,\n    options: {\n     \/\/ WordPress is the GraphQL url.\n     url: process.env.WPGRAPHQL_URL || https:\/\/wpgatsbydemo.wpengine.com\/graphql,\n  },\n},<\/code><\/pre>\n\n\n\n

Now, we\u2019ll replace the starter\u2019s data source endpoint URL with our own WordPress site URL:<\/p>\n\n\n\n

\/\/ gatsby-config.js file\n{\n  resolve: `gatsby-source-wordpress`,\n  options: {\n    url: `http:\/\/gatsbywpv4.local\/graphql`,\n  },\n},<\/code><\/pre>\n\n\n\n

Let\u2019s make sure we are in the my-wpstarter<\/code> project directory. From the project folder, we\u2019ll run the gatsby develop<\/code> 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<\/code> plugin fetching data, including errors and successful site processes along the way.<\/p>\n\n\n\n

If we see a success Building development bundle<\/code> message at the end, that means the Gatsby site build process is complete and the site can be viewed at http:\/\/localhost:8000<\/code>.<\/p>\n\n\n\n

\"The<\/figure>\n\n\n\n

This is a bare-bone starter blog with basic files and a few components. It\u2019s file structure is very similar to the gatsby-starter-blog<\/a>, except this one has a templates folder<\/a> that includes blog-post.js<\/code> and blog-post-achive.js<\/code> template files.<\/p>\n\n\n\n

When we view the GraphiQL API explorer at http:\/\/localhost:8000\/___graphql<\/code> we can see all of the data from WordPress exposed by WPGraphQL, as well as query and retrieve specific data right from the UI.<\/p>\n\n\n\n

\"The
This example shows a query for menu items in WordPress (middle panel) and the returned data of that query (right panel).<\/figcaption><\/figure>\n\n\n\n

You got it! Gatsby assumes the rest is up to us to build, using Gatsby components that pull in WordPress data for the presentation.<\/p>\n\n\n

Option 2: Building from scratch<\/h3>\n\n\n

Gatsby\u2019s documentation offers a detailed step-by-step guide<\/a> on how to create a new WordPress-Gatsby site from scratch using Gatsby\u2019s default starter theme<\/a>.<\/p>\n\n\n\n

We\u2019ll spin up a new project from the command line:<\/p>\n\n\n\n

#! create a new Gatsby site\ngatsby new wpgatsby-from-scratch-demo<\/code><\/pre>\n\n\n\n

This gets us a wpgatsby-from-scratch-demo<\/code> folder that includes the starter theme. From here, we\u2019ll cd<\/code> into that folder and start developing:<\/p>\n\n\n\n

cd wpgatsby-from-scratch-demo\ngatsby develop<\/code><\/pre>\n\n\n\n

Now we can open up http:\/\/localhost:8000<\/code> in the browser and get the welcome page.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

Now we are good to go to get start grabbing data from our WordPress site. Let\u2019s install the Gatsby Source Plugin:<\/p>\n\n\n\n

#! install with rpm\nnpm install gatsby-source-wordpress\n\n#! install with yarn\nyarn add Gatsby-source-wordpress<\/code><\/pre>\n\n\n\n

If we check our browser now, you\u2019ll noticed that nothing happens\u2009\u2014\u2009we still get the same Gatsby welcome. To fetch our WordPress site data, we need to add the plugin to the gatsby-config.js<\/code> file. Open the file and insert the following:<\/p>\n\n\n\n

\/\/ gatsby-config.js\nmodule.exports = {\n  siteMetadata: {\n    \/\/ ...\n  },\n  plugins: [\n  \/\/ Add Gatsby-source-wordpress plugin\n  {\n      resolve: `gatsby-source-wordpress`,\n      options: {\n        \/*\n         * The full URL of the WordPress site's GraphQL API.\n         * Example : 'https:\/\/www.example-site.com\/graphql'\n         *\/\n        url: `http:\/\/gatsbywpv4.local\/graphql`,\n       },\n     },\n    \/\/ The following plugins are not required for gatsby-source-wordpress ....\n  ],\n}<\/code><\/pre>\n\n\n\n

Just like last time, we need to change the WordPress data endpoint source to the URL of our WordPress site. Let\u2019s run gatsby develop<\/code> in our terminal to start things up.<\/p>\n\n\n\n

\"Two
Now we see that the createPages<\/code> function is running successfully to build a development bundle (left), and that WordPress data for posts, pages, taxonomies, users, menus, and everything else are fetched (right).<\/figcaption><\/figure>\n\n\n\n

However, when we open http:\/\/localhost:8000<\/code> 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<\/code>) then we see all WordPress data exposed to our Gatsby site that we can query and display as we want.<\/p>\n\n\n\n

\"The
GraphiQL shows that WordPress data is indeed exposed and we are able to create and execute queries.<\/figcaption><\/figure>\n\n\n\n

Let\u2019s test the following query I pulled straight from Gatsby’s tutorial, in the GraphiQL explorer:<\/p>\n\n\n\n

query {\n  allWpPost {\n    nodes {\n      id\n      title\n      excerpt\n      slug\n      date(formatString: \"MMMM DD, YYYY\")\n    }\n  }\n}<\/code><\/pre>\n\n\n\n

When we run the above query, we will see the allWpPost.nodes<\/code> property value, with sub properties for id<\/code>, title<\/code>, excerpt<\/code>, and others.<\/p>\n\n\n\n

Now, let\u2019s open our src\/components\/pages\/index.js<\/code> component file and replace the code with this:<\/p>\n\n\n\n

\/\/ src\/components\/pages\/index.js\nimport  React from \"react\"\nimport { graphql } from \"gatsby\"\nimport Layout from \"..\/components\/layout\"\nimport SEO from \"..\/components\/seo\"\n\nexport default function Home({ data }) {\n  return (\n    <Layout>\n      <SEO title=\"home\" \/>\n      <h1>My WordPress Blog<\/h1>\n      <h4>Posts<\/h4>\n      {data.allWpPost.nodes.map(node => (\n        <div>\n          <p>{node.title}<\/p>\n          <div dangerouslySetInnerHTML={{ __html: node.excerpt }} \/>\n        <\/div>\n      ))}\n    <\/Layout>\n  )\n}\n\nexport const pageQuery = graphql`\n  query {\n    allWpPost(sort: { fields: [date] }) {\n      nodes {\n        title\n        excerpt\n        slug\n      }\n    }\n  }\n`<\/code><\/pre>\n\n\n\n

Save it, restart the server with gatsby develop<\/code>, and refresh the page. If the build was successful, then our site\u2019s homepage should display a list of sorted blog posts from WordPress!<\/p>\n\n\n\n

Following the tutorial<\/a>, let\u2019s 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\u2019s foundational tutorial<\/a>, which we will follow here as well.<\/p>\n\n\n\n

As described in the tutorial, Gatsby uses createPages<\/code> API, or what it calls as its “workhorse” API, to programmatically create pages from data (from Markdown or WordPress). Unlike Markdown data, we don\u2019t need to create a slug here because each WordPress post has its own unique slug which can be fetched from the WordPress data endpoint.<\/p>\n\n\n

Creating pages for each post<\/h4>\n\n\n

Gatsby uses the gatsby-node.js<\/code> file, located at the root of our project, to programmatically create blog post. Let\u2019s open the gatsby-node.js<\/code> file in our text editor add the following code from the tutorial<\/a>.<\/p>\n\n\n\n

\/\/ gatsby-node.js \nconst path = require(`path`)\n\nexports.createPages = ({ graphql, actions }) => {\n  const { createPage } = actions\n  return graphql(`\n    {\n      allWpPost(sort: { fields: [date] }) {\n        nodes {\n          title\n          excerpt\n          content\n          slug\n        }\n      }\n    }\n  `).then(result => {\n    console.log(JSON.stringify(result, null, 4))\n    process.exit()\n  })\n}<\/code><\/pre>\n\n\n\n

As noted in the Gatsby Part 7 tutorial<\/a>, the above code is the first part of creating our post pages from WordPress data source. Following the guide, let\u2019s restart our server and develop our site with gatsby develop<\/code>.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

We should see console.log<\/code> 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.<\/p>\n\n\n

Creating blog post templates<\/h4>\n\n\n

Let\u2019s create a src\/components\/templates<\/code> folder in the src\/<\/code> directory and create a blog-post.js<\/code> file by pasting the following code snippets from the tutorial:<\/p>\n\n\n\n

\/\/ src\/templates\/blog-post.js\nimport React from \"react\"\nimport Layout from \"..\/components\/layout\"\nimport { graphql } from \"gatsby\"\n\nexport default function BlogPost({ data }) {\n  const post = data.allWpPost.nodes[0]\n  console.log(post)\n  return (\n    <Layout>\n      <div>\n        <h1>{post.title}<\/h1>\n        <div dangerouslySetInnerHTML={{ __html: post.content }} \/>\n      <\/div>\n    <\/Layout>\n  )\n}\nexport const query = graphql`\n  query($slug: String!) {\n    allWpPost(filter: { slug: { eq: $slug } }) {\n      nodes {\n        title\n        content\n      }\n    }\n  }\n`<\/code><\/pre>\n\n\n\n

As explained in the tutorial, the above code snippets create a single post with React JSX and wraps post.title<\/code> and post.content<\/code> (lines 12-13) around the src\/components\/layout.js<\/code> 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<\/code>. This variable is passed to the blog-post.js<\/code> template when the page is created in gatsby-node.js<\/code>.<\/p>\n\n\n\n

Next we should also update lines 12-13 of our gatsby-node.js<\/code> file with the following code from the tutorial.<\/p>\n\n\n\n

\/\/ gatsby-node.js\nconst path = require(`path`)\n\n exports.createPages = ({ graphql, actions }) => {\n   const { createPage } = actions\n   return graphql(`\n     {\n       allWpPost(sort: { fields: [date], order:DEC }) {\n         nodes {\n           title\n           excerpt\n           content\n           slug\n         }\n       }\n     }\n   `).then(result => {\n    result.data.allWpPost.nodes.forEach(node => {\n        createPage({\n          path: node.slug,\n          component: path.resolve(`.\/src\/templates\/blog-post.js`),\n          context: {\n            \/\/ This is the $slug variable passed to blog-post.js\n            slug: node.slug,\n          },\n        })\n      })\n   })\n }<\/code><\/pre>\n\n\n\n

Let\u2018s stop and restart our local server with gatsby develop<\/code> 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<\/code> we should see the following 404 page with a list of individual pages and posts links.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

If we check http:\/\/localhost:8000\/hello-gatsby-world<\/code>, we should our “Hello Gatsby WordPress World” post in all its glory.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

The next step is to link the post titles from the homepage to the actual posts.<\/p>\n\n\n

Linking to posts from the homepage<\/h4>\n\n\n

Linking the work from the homepage to post pages is done by wrapping post titles in the index.js<\/code> file with Gatsby\u2018s Link<\/code> component. Let\u2019s open the index.js<\/code> file that we created earlier and add the Link<\/code> component:<\/p>\n\n\n\n

\/\/ src\/components\/pages\/index.js\nimport React from \"react\"\nimport { Link, graphql } from \"gatsby\"\nimport Layout from \"..\/components\/layout\"\nimport SEO from \"..\/components\/seo\"\n\nexport default function Home({ data }) {\n  return (\n    <Layout>\n      <SEO title=\"home\" \/>\n     {\/* <h1>My WordPress Blog<\/h1>\n      <h4>Posts<\/h4> *\/}\n      {data.allWpPost.nodes.map(node => (\n        <div key={node.slug}>\n          <Link to={node.slug}>\n            <h2>{node.title}<\/h2>\n          <\/Link>\n          <div dangerouslySetInnerHTML={{ __html: node.excerpt }} \/>\n        <\/div>\n      ))}\n    <\/Layout>\n  )\n}\n\nexport const pageQuery = graphql`\n  query {\n    allWpPost(sort: { fields: [date], order: DEC  }) {\n      nodes {\n        title\n        excerpt\n        slug\n      }\n    }\n  }\n`<\/code><\/pre>\n\n\n\n

We imported the Link<\/code> component from Gatsby and then wrapped the post title with the Link<\/code> component and reference the slug of the post. Let\u2019s clean up the code by commenting out the page title, changing the title element to <h2><\/code>, and adding sorted posts order to DEC<\/code> in our graphql<\/code> query as well as the gatsby-node.js<\/code> file.<\/p>\n\n\n\n

As we did earlier, let\u2019s stop and restart the development server with gatsby develop<\/code>, and view our homepage at http:\/\/localhost:8000<\/code>. The post title should link to single post page.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

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<\/a> and query other data types\u2009\u2014\u2009like custom post types<\/a>\u2009\u2014\u2009and configure incremental build and previews<\/a> etc.<\/p>\n\n\n\n

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! <\/p>\u2014Gatsby tutorial doc<\/a> <\/cite><\/blockquote>\n\n\n

Option 3: Using Gatsby\u2019s WordPress Twenty Twenty Starter<\/h3>\n\n\n

Gatsby\u2019s starter template<\/a> for the default WordPress Twenty Twenty theme is created and maintained by Henrik Wirth<\/a>, who also has an extremely detailed and thorough step-by-step guide<\/a> 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<\/a>. It maintains the same Twenty Twenty styling in the Gatsby front-end site, but has few limitations<\/a>\u2009\u2014\u2009including, comments, monthly archive pages, and tags\u2009\u2014\u2009that are unsupported.<\/p>\n\n\n\n

First let\u2019s clone the starter in our twenty-twenty-starter<\/code> folder.<\/p>\n\n\n\n

#! clone gatsby-starter-wordpress-twenty-twenty \ngatsby new twenty-twenty-starter https:\/\/github.com\/henrikwirth\/gatsby-starter-wordpress-twenty-twenty\n<\/code><\/pre>\n\n\n\n

Let\u2019s cd<\/code> into that folder and then run gatsby develop<\/code> to spin up the site. It won\u2019t work properly the first time because we have not changed our WPGRAPHQL_URL<\/code> value yet in the env.example<\/code> file. We need to rename the file from .env.example<\/code> to simply .env<\/code>, as suggested in the documentation.<\/p>\n\n\n\n

After that, restart the development server with gatsby develop<\/code>. It should build the site successfully.<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

The menu may or may not appear depending on how the WordPress menu is named. The starter\u2019s menu slug for querying menu items is primary<\/code> in Menu.js<\/code> (line 8). Because I had set my WordPress site up using main-menu<\/code> instead, I had to update the Menu.js<\/code> file accordingly.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Because the starter was tested with older versions of our tools\u2009,\u2009I decided bump up the plugins\u2009 to the latest versions\u2009\u2014\u2009WPGraphQL 1.2.6, WPGatsby 1.0.6, and Gatsby Source WordPress\u2009 4.0.1 \u2014\u2009and it worked fine without any errors.<\/p>\n\n\n\n

The Twenty Twenty starter follows the file structure of the Twenty Nineteen Gatsby theme<\/a>, as well as Gatsby Starter WordPress Advanced<\/a>. Henrik Wirth describes how WordPress data is ported to Gatsby in his step-by-step guide<\/a>, as does Muhammad Muhsin<\/a> in a tutorial<\/a>. Otherwise, creating pages, page templates, porting menu items is exactly the same.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

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.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

If you are happy with WordPress Twenty Twenty styling, then that\u2019s it. Enjoy your new decoupled Gatsby site!<\/p>\n\n\n\n

But let\u2019s say we want to work with custom styles. The CSS files are imported from the assets<\/code> folder via the gatsby-browser.js<\/a><\/code> file.<\/p>\n\n\n\n

\"Screenshot<\/figure>\n\n\n\n

Let\u2019s modify the styles for the site\u2019s header, footer, posts and pages. Gatsby provides different options to style<\/a> its components and, in this project, I followed the CSS module<\/a> for styling and modified CSS markup of the Twenty Twenty starter components accordingly.<\/p>\n\n\n\n

We can start by creating a style folder at src\/components\/styles<\/code> and, inside it, a base<\/code> folder. Here\u2019s the general file structure we\u2019re aiming for:<\/p>\n\n\n\n

#! partial structure of \/style folder\nsrc\n |--\/components\n   |--\/styles\n     |--main.css          \n     |--\/base\n       |--reset.css\n       |--variables.css\n     |--\/scss\n       |--header.module.css\n       |--mainNav.module.css\n       |--footer.module.css\n       |--elements.module.css\n       \/\/ and so on...<\/code><\/pre>\n\n\n\n

We want to style the site\u2019s header and footer, so let’s open up the Header.js<\/code> and Footer.js<\/code> components in the starter and replace the code with the following:<\/p>\n\n\n\n

\/\/ src\/components\/Header.js\nimport React from \"react\"\nimport { graphql, Link, useStaticQuery } from \"gatsby\"\nimport Menu from \".\/menu\"\nimport style from \"..\/styles\/scss\/header.module.css\"\nimport logo from '..\/images\/gatsby-icon.png'\n\nconst Header = ( ) => {\n  const { wp } = useStaticQuery(graphql`\n    {\n      wp {\n        generalSettings {\n          title\n          description\n        }\n      }\n    }\n  `)\n  return (\n    <header className={style.masthead}>\n      <div className={style.masthead_info}>\n\n      <Link to=\"\/\">\n        <img src={logo} alt=\"logo\" width=\"100\" height=\"100\" display=\"inline-block\" marginBottom= \"0\"  className={style.site_logo} \/>\n      <\/Link>\n      <div className={style.site_header} >\n        <div className={style.site_title}>\n          <Link\n            to=\"\/\"\n            dangerouslySetInnerHTML={{ __html: wp.generalSettings.title }} \/>\n        <\/div>\n        <div className={style.site_description} dangerouslySetInnerHTML={{ __html: wp.generalSettings.description }} \/><\/div>\n\n      <\/div>\n      <Menu \/>\n    <\/header>\n  )\n}\n\nexport default Header<\/code><\/pre>\n\n\n\n

Similarly, the Footer.js<\/code> component was modified as follows:<\/p>\n\n\n\n

\/\/ src\/components\/Footer.js\nimport React from \"react\"\n\nimport style from \"..\/styles\/scss\/footer.module.css\"\n\nexport default () => (\n  <footer className={style.colophon}>\n    <p>\u00a9 {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>\n  <\/footer>\n)<\/code><\/pre>\n\n\n\n

Now, let\u2019s restart our development server. We should see the following, including a new customized header and footer. I used the same style from Learning Gatsby<\/a> which is an online course by Morten Rand-Hendriksen (I am a fan!).<\/p>\n\n\n\n

\"Screenshot
Screenshot showing modified header and footer styling.<\/figcaption><\/figure>\n\n\n\n

You can grab the all the code I used over at GitHub<\/a>.<\/p>\n\n\n

What all this means for WordPress enthusiasts<\/h3>\n\n\n

There are many posts that compare the advantages and disadvantages of a decoupled WordPress and Jamstack site like the Gatsby examples we\u2019ve covered. In my research, I realized that none of them are as exhaustive as what Chris already wrote in \u201dWordPress and Jamstack\u201d<\/a> where he compares everything, from performance and features, to the developer experience and build processes, and beyond.<\/p>\n\n\n\n

I found the following articles draw some helpful conclusions on a variety of topics, including:<\/p>\n\n\n

What\u2019s the cost?<\/h4>\n\n\n

The general assumption is that Jamstack hosting is cheap, and cheaper than traditional LAMP stack hosting. But there\u2019s actually quite a bit to consider and your actual costs might vary.<\/p>\n\n\n\n