Top Tips when moving your WordPress site to Gatsbyjs.

Following a recent migration of JSdiaries to a static site generator. I encountered a number of obstacles. Essentially, in this migration, you are using Gatsby’s WordPress plugin to communicate with your WP site as a hosted backend to query your data from.

Once queried, your data, images, fonts etc are all transformed into static assets resulting in a very performant website with no external network requests.

While the idea of this migration might seem relatively simple I experienced some time consuming setbacks and I wanted to highlight these issues for those in a similar position.

If you want to know why I migrated my site to Gatsby check out my previous post here.

HTTPS

The secure version of HTTP, Hyper Text Transfer Protocol Secure (HTTPS) is fast becoming the standard across the web for encrypted communication between the browser and the desired website.

Using Gatsby’s WordPress plugin in gatsby.config.js  you can specify whether or not you want to use HTTP or HTTPS.

 
{
      resolve: `gatsby-source-wordpress`,
      options: {
        /*
        * The base URL of the WordPress site without the trailingslash and the protocol. This is required.
        * Example : 'gatsbyjswpexample.wordpress.com' or 'www.example-site.com'
        */

        baseUrl: `dev-gatbsyjswp.pantheonsite.io`,
        // The protocol. This can be http or https.
        protocol: `http`,
        // Indicates whether the site is hosted on wordpress.com.
        // If false, then the asumption is made that the site is self hosted.
        // If true, then the plugin will source its content on wordpress.com using the JSON REST API V2.
        // If your site is hosted on wordpress.org, then set this to false.
        hostingWPCOM: false,
        // If useACF is true, then the source plugin will try to import the WordPress ACF Plugin contents.
        // This feature is untested for sites hosted on WordPress.com
        useACF: true,
      },
    },
  ],
}

For a more detailed overview of HTTPS have a look here. Most WordPress hosted sites can easily enable the use of HTTPS.

But, why is this important?  Well, when deploying your Gatsby site using hosting services such as Netlify you may experience a Insecure Mixed Content warning. This indicates that some of your content is served over HTTP and some over HTTPS.

This can lead to services like Netlify omitting some of your insecure content such as images and other assets which can be quite frustrating but its not without good reason.

I was facing a problem where the images in my blog post content was being served over http whilst other assets over https. This was easily rectified by using a WP plugin called Really Simple SSL which ensured all of my sites assets are served over HTTPS.

You might be asking, why is this necessary if a Gatsby sites only uses static assets? Well, while most of your data if transformed into static files, some external requests might remain. For example, using images in a non Markdown blog post will instead cause those image to be retrieved externally from your hosted WordPress instance rather than from your static assets.

Advanced Custom Fields(ACF)

Advanced Custom Fields is one of the most popular ways of adding custom data properties to blog posts or any other kind of data you want retrieved from your site.

I use it to add additional image fields to my blog posts. For example, I might want one image property to represent how my blog post looks in the blog listing page.

Like this:

And another image property to represent the banner image shown when opening that post:

These new data properties also need to be exposed to our WordPress /wp-json/wp/v2/posts endpoint. Which can be achieved using an additional plugin called ACF-To-Rest-API.

Once this plugin was activated, I used a GraphQL query in gatsby-node.js to request the additional ACF fields in the data response.

graphql(
        `
        {
          allWordpressPost {
            edges {
              node {
                id
                wordpress_id
                date
                guid
                modified
                slug
                status
                type
                link
                title
                content  
                acf {
                  description
                  title
                  icon
                  link
                }
      
                }
              }
            }
          }
        }
        `
      )

GraphQL Error – Unknown Field on ACF

I experienced some issues when querying my posts with ACF fields. Some of  the posts had no data for the image fields. This is because I had not gone back to some of my older posts and populated them with images.

For these cases, WordPress returns a value of false which Gatsbyjs did not like because its expecting an array or null.

Thankfully, this issue was well documented and the fix is in the bottom of this repo.

Simply navigate to your functions.php file in WordPress and add the following snippet:

function nullify_empty($value, $post_id, $field)
{
    if (empty($value)) {
        return null;
    }

    return $value;
}

add_filter('acf/format_value/type=image', 'nullify_empty', 100, 3);
add_filter('acf/format_value/type=relationship', 'nullify_empty', 100, 3);
// not sure if gallery is internally named gallery as well but this should work
add_filter('acf/format_value/type=gallery', 'nullify_empty', 100, 3); 

This ensures that your WordPress instance will always return null for a custom ACF image field allowing GraphQL to iterate through all ACF data.

Image Sharpening

GraphQL allows you to customize the resolution of your retrieved images in its typed query language. This is incredibly useful when not wanting to download a larger version of an image that you intend on downscaling in an application.

This practice very much feeds into the Gatsbyjs mantra by having optimised static files that make a website fast and performant.

Gatsby provides a full tutorial that helps setup this process here.

Lets take a look at a GraphQL query that customises an image size while combining it with Advanced Custom Fields for more relevance.

{
          allWordpressPost {
            edges {
              node {
                id
                wordpress_id
                date
                guid
                modified
                slug
                status
                type
                link
                title
                content  
                acf {
                  description
                  title
                  icon
                  link
                  image {
                    localFile{
                      childImageSharp{
                          resolutions(width:500, height: 200){
                              src
                              width
                              height
                          }
                      }
                  }
                }
      
                }
              }
            }
          }
        }

The ACF field image has a localFile property that uses childImageSharp to determine the desired custom resolution of that image. The plugin gatsby-plugin-sharp allows us to use childImageSharp like this.

Finally, to use the image in a React component we import Img from gatsby-image. and use it the render function with its props resolutions and key.

import React from "react"
import { graphql, Link } from "gatsby"
import Img from "gatsby-image"

const IndexPage = ({ data }) => {
  const imagesResolutions = data.allWordpressPost.edges.map(
    edge =>
      edge.node.childWordPressAcfPostPhoto.photo.localFile.childImageSharp
        .resolutions
  )
  return (
    

Hi people

Welcome to your new Gatsby site.

Now go build something great.

{imagesResolutions.map(imageRes => ( ))} Go to page 2
) } export default IndexPage export const query = graphql` query { allWordpressPost { edges { node { childWordPressAcfPostPhoto { photo { localFile { childImageSharp { # edit the maxWidth value to generate resized images resolutions(width: 500, height: 500) { ...GatsbyImageSharpResolutions_withWebp_tracedSVG } } } } } } } } } `

Debugging

There is a strong likelihood in running in to various errors in this migrations process. Here are some things I learned.

Plugins

A WordPress instance most likely has enabled many plugins for different units of its functionality. From my experience I found out that some of them conflict with Gatsby’s WordPress plugin when its retrieving nodes of data.

If the error is not descriptive and its not obvious what the issue is, a good rule of thumb is to disable all your WordPress plugins and add them back in one by one until the culprit has been discovered.

Even very useful plugins such as Jetpack may have security rules to disallow some data being exposed from an endpoint.

GraphQL Queries

When you are unsure of what data is available to your via a GraphQL query. It would be very cumbersome if you had to find out through trial and error when using

When using the command:

gatsby develop

By navigating to the url http://localhost:8000/___graphql we get an additional explorer window that allows us to navigate through the graphQL data schema.

By pressing CTRL+Spacebar we get a dropdown list of all possible data types so:

Community

If all else fails for the issue your working on the community is always willing to help out. Gatsbyjs has a thriving community, people are very excited about this technology and rightly so. I’d recommend checking out these outlets to discuss an issue your having:

Overall, I’d really recommend a migration like this from WordPress or any other host. Aside from the performance benefits of using a static site generator I learned a lot of useful things in the process.

In the future, I intend to take advantage of other Gatsbyjs plugins in order to optimise and add more functionality to my site. I’m excited to see what else this static site generator is capable of.

 

Gareth Dunne

Full Stack Developer and creator of JSdiaries. Passionate about the latest in web technologies and how it can provide value for my clients.