Preparing GatsbyJS Site for Deployment

Note: This is part of Learning GatsbyJS post series. This learning post is still in active development and updated regularly.

In the previous two learning note posts series: Learning GatsbyJS and Adding Functionality to Gatsby sites, basic Gatsby setup, adding posts, and adding functionalities (eg. typograpgy, images, tags, navigation) were discussed.  The next logical step in building a Gatsby site is to improve site performance with Gatsby plugins and adding SEO component. In this post, how to prepare a Gatsby site prior to deployment in GitHub pages or Netlifly is discussed.

Prerequisite

Note: Deploying Gatsby sites to GitHub pages or Netlifly requires working knowledge with Git version control. In a separate post Learning to Work with Git and GitHub, some basic command in using Git & GitHub are discussed.

In this post common steps suggested in the Gatsby tutorial for site improvement through addition of progressive app manifest, service worker and SEO component prior to deployment are discussed.

Gatsby Sites & Progressive Web App

The core selling pitch of GatsbyJS is to build blazing fast website & app out of the box by “code splitting, code modification, and optimization like pre-loading background and image processing, etc.”

Progressive web app” (PWA) is both a general term for a new philosophy toward building websites and a specific term with an established set of three explicit, testable, baseline requirements, which must – (i) run under HTTPS, (ii) include a Web App Manifest, and (iii) implement a service worker. Gatsby Docs | Progressive web app

To qualify a website PWA, it should meet the following three baseline criteria:

(i) The site must run under https. Any website to qualify for PWA should be able run with https for security reason. But this is upto the user and not associated with Gatsby build process.

(ii) The site must include a Web App Manifest file. A web app manifest is JASON file which provides the browser site or app information (eg. name, site icon, start-url, background etc.,) that could be saved in users’ home screen. In Gatsby, this feature could be added with gatsby-plugin-manifest.

(iii) The site must implement a service worker. A service worker could provide offline support even when network connection is bad by running the script for push notification, background script in the background. In Gatsby sites, this feature could be added with gatsby-plugin-offline.

To qualify a Gatsby build site as PWA, the above mentioned three criteria should be full filled by following three steps.

Step 1: Adding Manifest File

Gatsby plugin manifest adds a manifest.webmanifest file to convert Gatsby sites into progressive apps allowing users to add features like favicon or icon generation, page catching etc. Gatsby recommends installing this plugin together with Gatby’s offline plugin.

If the Gatsby’s manifest plugin is not install already, install it with either npm or yarn as follows:

#! add with npm
npm install --save gatsby-plugin-manifest

#! add with yarn
yarn add gatsby-plugin-manifest

The next step is to add favicon for the site, which can be added at src/images/ folder as src/images/icon.png.

// gatsby-config.js
//Source: https://www.gatsbyjs.org/tutorial/part-eight/

{
  plugins: [
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `MasterBlog`,
        short_name: `MasterBlog`,
        start_url: `/`,
        background_color: `#6b37bf`,
        theme_color: `#6b37bf`,
        display: `standalone`,
        icon: `src/images/icon.png`, 
      },
    },
  ]
}

The above example from the Gatsby tutorial showing plugin configurion in the gatsby-config.js file. Additional Information: Gatsby's-plugin-manifest Doc

Step 2: Adding Offline Support

Other requirement recommended in Gatsby’s tutorial is to add Gatsby’s offline plugin to create a service worker service for the site in the background so that the site works offline allowing for seamless offline experience. The gatsby-config.js file (step 1) is updated as shown below:

// gatsby-config.js
//Source: https://www.gatsbyjs.org/tutorial/part-eight/

{
  plugins: [
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `MasterBlog`,
        short_name: `MasterBlog`,
        start_url: `/`,
        background_color: `#6b37bf`,
        theme_color: `#6b37bf`,
        display: `standalone`,
        icon: `src/images/icon.png`, 
      },
    },
    `gatsby-plugin-offline`,
  ]
}

In the example above, the gatsby-plugin-offline is added as a plugins array (line 18) in gatsby-config.js.

Step 3: Adding Page Metadata

In a typical website, site metadata like title, site-description, author etc are added at the document head section to help search engines (eg. Google) to display in the search result page.

In Gatsby site, React Helmet package is used to manage document head as React component interface. As stated in the Gatsby tutorial : “Gatsby’s react helmet plugin provides drop-in support for server rendering data added with React Helmet“. When site is build with gatsby build, the attributes added in React Helmet will be passed to the static HTML pages.

1. Install React Helmet and Gatsby’s React helmet plugin

If not already added, install the React Helmet and gatsby-plugin-react-helmet plugins packages.

#! add with yarn
yarn add gatsby-plugin-react-helmet react-helmet

#! add with npm
npm install --save gatsby-plugin-react-helmet react-helmet

2. Configure Site Metadata in gatsby-config.js File

If not already added site metadata attributes (eg. title, description, authors, etc) in the gatsby-config.js file, add these attributes as shown below (lines: 5-7).

// gatsby-config.js
//Source: https://www.gatsbyjs.org/tutorial/part-eight/
module.exports = {
  siteMetadata: {
    title: `MasterBlog`,
    description: `A test Gatsby site for contents & images `,
    author: `TinjureWP`,
  },
{
  plugins: [
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `MasterBlog`,
        short_name: `MasterBlog`,
        start_url: `/`,
        background_color: `#6b37bf`,
        theme_color: `#6b37bf`,
        display: `standalone`,
        icon: `src/images/icon.png`, 
      },
    },
    `gatsby-plugin-offline`,
    `gatsby-plugin-react-helmet`,
  ]
}

Add the gatsby-plugin-react-helmet as plugins array in the gatsby-config.js file (line 24) after the gatsby-plugin-offline.

3. Create src/components/seo.js file

Create a site metadata component as seo.js, as described in the Gatsby tutorial inside src/component folder.

// src/components/seo.js
//source:https://www.gatsbyjs.org/tutorial/part-eight/#add-page-metadata 

import React from "react"
import PropTypes from "prop-types"
import Helmet from "react-helmet"
import { useStaticQuery, graphql } from "gatsby"

function SEO({ description, lang, meta, title }) {
  const { site } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
            description
          }
        }
      }
    `
  )

  const metaDescription = description || site.siteMetadata.description

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}
      title={title}
      titleTemplate={`%s | ${site.siteMetadata.title}`}
      meta={[
        {
          name: `description`,
          content: metaDescription,
        },
        {
          property: `og:title`,
          content: title,
        },
        {
          property: `og:description`,
          content: metaDescription,
        },
        {
          property: `og:type`,
          content: `website`,
        },
        {
          name: `twitter:card`,
          content: `summary`,
        },
        {
          name: `twitter:creator`,
          content: site.siteMetadata.author,
        },
        {
          name: `twitter:title`,
          content: title,
        },
        {
          name: `twitter:description`,
          content: metaDescription,
        },
      ].concat(meta)}
    />
  )
}

SEO.defaultProps = {
  lang: `en`,
  meta: [],
  description: ``,
}

SEO.propTypes = {
  description: PropTypes.string,
  lang: PropTypes.string,
  meta: PropTypes.arrayOf(PropTypes.object),
  title: PropTypes.string.isRequired,
}

export default SEO

In the example above adopted from Gatsby starter blog is basic metadata tags shown as an example.

4. Adding the <Seo > component to templates and pages and pass the props to it. As an example the <seo > component is added to the /src/templates/blog-post.js as shown below:

// src/templates/blog-post.js
import React from 'react';
import Img from 'gatsby-image';
import { graphql } from "gatsby"
import Layout from '../components/layout';
import PrevNext from '../components/prevnext';
import SEO from "../components/seo"

function BlogPost(props) {
    const post = props.data.markdownRemark
    const { title } = props.data.markdownRemark.frontmatter;
  const tags = props.data.markdownRemark.frontmatter.tags || [];
  const { prev, next } = props.pageContext;

  return (
      <Layout>
       <SEO title={post.frontmatter.title} description={post.excerpt} />
          <div>
          <h1 className="single-entry-title">{title}</h1>
// ...

In the above blog-post.js template example, the <Seo > component is imported from src/components/seo.js (line 7) and called just underneath <Layout > component (line 16) in line 17. The metadata props title and description are passed to the <Seo > component dynamically from the frontmatter of markdown posts (if available) or else from as defined in the gatsby-config.js file (see step 3, part two lines: 5-7).

Wrapping Up

In this learning-note post series, adding progressive app manifest, service worker features through Gatsby’s manifest plugin and gatsby-plugin-offline and a SEO component to improve site performance were discussed. In the next post, how to deploy a Gatsby site in GitHub pages or Netlify will be discussed.

Next Post: Learn to Deploy site with GitHub Pages and Netlify

Useful Resources

While preparing this post, I have referred the following references extensively. Please refer to the original posts for more detailed information.