Tutorial

How To Convert a Gatsby Site to a Progressive Web App

Published on July 22, 2021

Full-Stack Software Developer

How To Convert a Gatsby Site to a Progressive Web App

The author selected the Internet Archive to receive a donation as part of the Write for DOnations program.

Introduction

Gatsby is a popular framework for turning source material into static HTML files that are ready for instant deployment. Because of this, it is often called a Static Site Generator (SSG). As an SSG, it already has a positive impact on user experience (UX) by turning multiple content sources into an optimized website, but there is another layer available for UX improvement: Progressive Web App capabilities.

A Progressive Web App, or PWA, is a type of website that goes beyond the usual limits of web capabilities, using newer technology to bridge the gap between your browser and your operating system. PWAs encompass a lot of different features, such as offline browsing, installation support, and newer web APIs. By combining these features, PWAs deliver your users an improved overall browsing experience, as well as the option to use your website like any other application, complete with its own icon and app window.

Although there is a lot that goes into making an optimal PWA, Gatsby provides tools and support to streamline the process, such as a manifest file plugin (gatsby-plugin-manifest) and an offline plugin (gatsby-plugin-offline). This tutorial will walk you through using these plugins, as well as audit tools like Lighthouse, and by the end you will have learned how to take a Gatsby site and turn it into a fully-functional Progressive Web App.

Prerequisites

Before starting, here are a few things you will need:

  • A local installation of Node.js for running Gatsby and building your site. The installation procedure varies by operating system, but DigitalOcean has guides for Ubuntu 20.04 and macOS, and you can always find the latest release on the official NodeJS download page.
  • Some familiarity with JavaScript, for working in Gatsby. The JavaScript language is an expansive topic, but a good starting spot is our How to Code in JavaScript series.
  • An existing Gatsby project that does not yet have PWA support, but is otherwise functional. For satisfying this requirement and building a new Gatsby project from scratch, you can refer to Step 1 of the How to Set Up Your First Gatsby Website tutorial.
  • (Optional) An icon file for your website. In order to be installable, your PWA will need an icon with an original resolution of at least 512 x 512 pixels. If you do not have an icon in mind, this tutorial will instruct you to download a sample icon in Step 2.

This tutorial was tested on Node v14.17.2, npm v6.14.13, Gatsby v3.9.0, gatsby-plugin-offline v4.8.0, and gatsby-plugin-manifest v3.8.0.

Step 1 — Preparing Your Content (Optional)

As a prerequisite, you already have created a functional Gatsby site that can be built and deployed. However, you might not have any content for your site yet. In this step, you will prepare a sample smart home user guide site to demonstrate what kind of content benefits from PWA features.

As a smart home user guide is something likely to be visited multiple times by the same user, it makes a great example to showcase the main features of a PWA. The app-like qualities of a PWA, such as installation support and home screen icons, make it accessible on both mobile and desktop devices, and thanks to offline support, even when your home network fails, you or other residents can still access the guide.

Building off the starter template, you can add a new page for the smart home guide under src/pages. Create a file named src/pages/internet-issues.js, and add the following sample page code:

src/pages/internet-issues.js
import * as React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"
import Seo from "../components/seo"

const IndexPage = () => (
  <Layout>
    <Seo title="Internet Issues" />
    <h1>Internet Issues - Troubleshooting</h1>
    <p>Having issues connecting to the internet? Here are some things to try in our house.</p>
    <ul>
      <li>Your Device
        <ul>
          <li>Is airplane mode on? Is WiFi enabled?</li>
          <li>Is the device within range of the router or physically connected to the network via ethernet?</li>
          <li>Are you connected to the correct network?</li>
        </ul>
      </li>

      <br />

      <li>The Router / Modem
        <ul>
          <li>Have you checked the ISPs status page to check for an outage? You can use your smartphone and mobile data to check this.</li>
          <li>Have you tried rebooting the router and/or modem?</li>
          <li>Have you checked to make sure that all physical connections to and from the router and modem are secure?</li>
        </ul>
      </li>
    </ul>

    <br/>

    <p>
      <Link to="/">Back to homepage</Link> <br />
    </p>
  </Layout>
)

export default IndexPage

In this page code, you’ve provided troubleshooting instructions to your housemates or guests for when they are having trouble connecting to the internet. You have done so with a bulleted list, providing a link back to the homepage for easier navigation. Since this is a Gatsby project, you’ve created the entire page as a React component, which will nest your list inside a reusable Layout component and return the page as JSX so Gatsby can process it. For an optimized navigational experience, you’ve also used a Link component to link back to the homepage, instead of a regular HTML a tag.

Make sure to save the file after updating it, and you can go ahead and close it since you won’t need to update it again in this tutorial.

This page will be accessible at your_domain/internet-issues/, but you will also add a link to it from your homepage to make it easier to get to.

Open up src/pages/index.js, and add a direct link to the new page within the React component IndexPage, as shown in the following highlighted code:

src/pages/index.js
import * as React from "react"
import { Link } from "gatsby"
import { StaticImage } from "gatsby-plugin-image"

import Layout from "../components/layout"
import Seo from "../components/seo"

const IndexPage = () => (
  <Layout>
    ...

    <p>
      <Link to="/internet-issues/">Internet Issues Troubleshooting Page</Link> <br />
      <Link to="/page-2/">Go to page 2</Link> <br />
      ...
    </p>
  </Layout>
)

Save and close index.js with the added link.

You’ve now built a brand new page for your smart home user guide and added a link to get to it from your homepage. In the next step, you will be adding a special file known as a manifest file, which instructs web browsers on the specifics of your PWA setup.

Step 2 — Adding a Manifest File

The next step is fulfilling one of the core requirements of PWAs by adding a manifest JSON file, manifest.json. The manifest file tells the web browser details about your site and how to display it to the user if it is installed on the users’s OS, specifying details such as what icon to use and how it should be launched. You will use gatsby-plugin-manifest to generate this file by initializing the plugin in your Gatsby config file.

First, install the Gatsby plugin by running the following command in your Gatsby project directory:

  1. npm install gatsby-plugin-manifest

Next, you will provide some details to the plugin that tell it how you want the PWA to appear and act. You do this by editing the main Gatsby config file that lives in the root of your project directory, gatsby-config.js. Open this file and add the following code:

gatsby-config.js
module.exports = {
  plugins: [
    ...

    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `My Smart-Home Guide`,
        short_name: `SH Guide`,
        description: `Guide for residents of the ABC123 Smart Home`,
        start_url: `/`,
        background_color: `#0a68f0`,
        theme_color: `#0a68f0`,
        display: `standalone`,
        icon: `src/images/pwa-icon.png`,
        icons: [
          {
            src: `/favicons/pwa-icon-192x192.png`,
            sizes: `192x192`,
            type: `image/png`
          },
          {
            src: `/favicons/pwa-icon-512x512.png`,
            sizes: `512x512`,
            type: `image/png`
          }
        ]
      },
    }

    ...
  ]
}

Note: If you have started with the gatsby-starter-default template, you will already have some values for this plugin in your config file. In that case, overwrite the existing values with this code.

There are a lot of values in this file, so here is a quick explanation:

  • name and short_name should correspond with the name of your site and how you want the site to appear to users when installed. short_name appears on the home screen of the user’s device, or other places where space is limited, and name appears everywhere else.
  • description should be text that describes the purpose of your application.
  • start_url is used to suggest to the browser which page should open when the user launches the PWA from their launcher. A value of /, as used here, tells the browser you would like the user to land on your homepage when opening the PWA.
  • background_color and theme_color are both directives to the browser on styling the PWA, and the values should correspond to CSS color strings. background_color is only used while waiting on the actual stylesheet to load, as a placeholder background color, whereas theme_color is potentially used in multiple places outside the PWA, such as surrounding the icon on an Android home screen.
  • display is a special value because it dictates how your entire site acts as a PWA, and, unlike other fields which support hundreds of different combinations, can be one of four possible values: fullscreen, standalone, minimal-ui, or browser. In your config, the value of standalone makes the PWA act like a standalone application outside the standard web browser. In practice, this means that it acts similar to a native application—it gets its own launcher icon, application window, and the URL address bar is hidden.
  • icon is not one of the standard manifest fields, but is a special field within the context of gatsby-plugin-manifest. By using this property, and providing a path to a file that meets the minimum requirements (at least 512x512 pixels, square), the Gatsby plugin will automatically transform the image into a site favicon, as well as inject into the manifest as the required icons manifest property. By specifying icons with an array of filenames, sizes, and image types, you are invoking the Hybrid Mode Configuration of the manifest plugin. This takes your single source icon file and transforms it into the filenames and sizes specified. This is not strictly necessary, but it avoids any possible issues with deployments in environments like Apache, which don’t work with the default /icons directory.

Make sure to save the config file with your changes, but keep it open for the next step, where you will be adding another Gatsby plugin and configuring offline support.

In the manifest values, the path used for icon was src/images/pwa-icon.png, but you still need to place an image file at that location before it will work. If you have a square image file that is at least 512 x 512 pixels, you can copy it to that path. Otherwise, you can use a pre-formatted image file selected for this tutorial. To use the tutorial icon file, either download the sample icon file for this tutorial and save it at src/images/pwa-icon.png, or if you prefer the command line, use cURL from your project root directory:

  1. curl -o ./src/images/pwa-icon.png https://assets.digitalocean.com/articles/67869/1.png

This will download the image to the correct part of your Gatsby application. This is the only image file you’ll need; Gatsby will automatically generate the 192x192 version.

You have now configured your Gatsby project to serve a manifest JSON file with the correct values, which is a required part of enabling PWA capabilities. In the next step, you will be addressing another requirement of PWAs, offline support, by adding the feature via a service worker plugin, gatsby-plugin-offline.

Step 3 — Adding Offline Support with Service Workers

Another key component of PWAs is offline support, which you will implement with a piece of web technology known as a service worker. A service worker is essentially a bundle of JavaScript code that runs separately from all the code tied to the UI of the page you are on. This isolated code is also granted special privileges, such as the ability to alter the behavior of network requests, which is critical for implementing offline support. In this step, you will set up a robust service worker through the gatsby-plugin-offline plugin, configured through your Gatsby config file.

Start by installing the gatsby-plugin-offline package and adding it to your dependencies. You can do so with:

  1. npm install gatsby-plugin-offline

Next, load the plugin through the Gatsby config, the same gatsby-config.js edited in the previous step:

gatsby-config.js
module.exports = {
  plugins: [
    ...

    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        ...
      },
    },
    `gatsby-plugin-offline`,

    ...
  ]
}

Make sure to save the configuration file after adding the new plugin.

Warning: Both the docs for gatsby-plugin-manifest and for gatsby-plugin-offline specify that gatsby-plugin-offline should always come after gatsby-plugin-manifest in the configuration array, as shown in this code snippet. This ensures that the manifest file itself can be cached.

At this point, you’ve both added offline support and created a manifest file for your app. Next, this tutorial will explain the third necessary part of a PWA: having a secure context.

Step 4 — Providing a Secure Context

The last of the three basic minimum requirements for any PWA is that it run in a secure context. A secure context refers to a web environment in which certain baseline standards are met for authentication and security, and most often is referring to content served over HTTPS.

A secure context can be achieved in many ways. Because of this, this tutorial will describe a few different strategies to get a secure context, then move forward with testing your Gatsby site locally.

If you are deploying your Gatsby project through a static host, such as DigitalOcean’s App Platform, then it is likely that HTTPS is supported out of the box, with no setup required. For more information on deploying your app on App Platform, check out the How To Deploy a Gatsby Application to DigitalOcean App Platform tutorial.

If you are deploying on a server that does not automatically provide HTTPS, but you have SSH access, you can use Let’s Encrypt to obtain and install a free TLS/SSL certificate. For example, if you are using Apache with Ubuntu 20.04, you can follow How To Secure Apache with Let’s Encrypt on Ubuntu 20.04 to use Certbot to handle this process. If you are deploying to a shared host, you will want to check their specific documentation pages for if, and how, SSL certificate installation might be available.

For local testing, you don’t have to deal with obtaining or installing an SSL certificate. This is because most modern browsers treat localhost sites as a secure context, even without a TLS/SSL certificate installed or HTTPS protocol.

You now have successfully added PWA support to your Gatsby project by meeting the three baseline criteria: HTTPS (or a localhost secure context), a manifest file, and a service worker. The next step is to test and verify that it shows up correctly, with PWA features enabled.

Step 5 — Running Local Tests

In this step, you will run some local tests to make sure your PWA functionality is working properly. This is an initial testing step before using the Lighthouse tool for a more comprehensive audit.

To locally test your Gatsby site’s functionality as a PWA, build it and then serve the generated build directory:

  1. npm run build
  2. npm run serve

Once it is ready, you will see the following:

Output
You can now view gatsby-starter-default in the browser. ⠀ http://localhost:9000/

You can now visit that URL in your web browser, and if the browser supports PWAs, you will encounter some special additional UI elements. For example, on Chrome desktop, there will be a new button exposed in the address bar that, when clicked, asks if you would like to install the Gatsby site as an app, as shown in the following image:

Screenshot showing a popup menu, originating from the Chrome desktop address bar, asking if you would like to "Install app" for the Gatsby site ("My Smart-Home Guide") running on localhost

If you want to test your site locally on a smartphone, this is possible with something like Chrome’s remote debugging tool (Android only), or a localhost tunneling service such as ngrok. On mobile, you will encounter the same option to install your site as an app, as shown in the following:

Screenshot from an Android device, showing a "Install app" modal popup in the Chrome browser, for "My Smart-Home Guide", through localhost remote debugging

This PWA prompt is different for each device, operating system, and browser. Additionally, certain features such as Add to Home Screen might only be available on certain devices. Certain browsers running on specific devices might not support PWAs entirely; check caniuse.com for more information on platform support.

You have now verified that your Gatsby project can be built and served locally, with your browser successfully detecting that it offers PWA functionality. The next step will be a final check against what you have put together, and using the Lighthouse tool to check if there are areas for improvement.

Step 6 — Running an Audit with Lighthouse

At this point, you have a Gatsby site that meets all the core requirements for a PWA: it has HTTPS, a manifest, and a service worker for offline support. However, the concept of a PWA goes beyond any single requirement—it encompasses all of the facets working together, plus adhering to general guidelines. With this in mind, your last step is to use an audit tool to verify that you meet the baseline criteria, as well as gather information on how you can further optimize your Gatsby project to meet PWA best practices.

There are a few different ways to audit your site as a PWA, but at the moment the gold standard is the Lighthouse Tool. If you have desktop Chrome installed, you can run an audit against your site directly in the web browser DevTools.

First, navigate to your Gatsby site in Chrome, then open Chrome DevTools by right clicking anywhere on the webpage and selecting Inspect in the right click menu. Next, click the Lighthouse tab under DevTools. If you don’t see it, click the >> label next to the right-most tab to show tabs that are hidden due to size constraints.

Now, to actually run the report, uncheck everything on the Lighthouse tab except for Progressive Web App, and then hit Generate Report to analyze your site:

Screenshot showing the Lighthouse tab in desktop Chrome DevTools, with only the Progressive Web App report category checked

You can also generate this report programmatically, via the Lighthouse Node.js CLI. This command will run the PWA-only audit and then open the report for viewing:

  1. npx lighthouse http://localhost:9000 --only-categories=pwa --view

However, using Lighthouse via CLI does not bypass the need to have Chrome installed; this just makes it easier to automate the process.

The report generated by Lighthouse tells you a few things, broken down into categories. Some of the most important are:

  • Installable: This is the most important category, and addresses whether or not your site meets the three baseline criteria for being an installable PWA—HTTPS, manifest files, and a service worker.
  • PWA Optimized: These are things that you should be doing for an optimal PWA user experience, but aren’t strictly required for your PWA to be functional. Think of these as best-practice suggestions. Some examples of these are creating a custom splash screen to display during mobile app loading, setting a theme color for the address bar, and providing fallback content for when JavaScript is unavailable. If you’d like to look at the full list, check out the official Lighthouse documentation.

By using the Lighthouse tool to audit your Gatsby PWA, you not only now have a functional PWA, but also have an idea of how it meets PWA requirements and best practices.

Conclusion

After following these steps, you now have a Gatsby site that can also function as a modern installable Progressive Web App, with strong offline support. You are now providing your users with the best of both worlds: They can browse your site as a normal web page, but they can also use it as they would a native application, with its own launcher icon, display window, and the reliable performance they expect from native applications.

If you are looking for more ways to deliver the most optimized PWA experience possible, in addition to the Lighthouse PWA audit, Google also has a published a PWA checklist that will help. If you would like to read more on Gatsby, check out the rest of the How To Create Static Web Sites with Gatsby.js series.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products


Tutorial Series: How To Create Static Web Sites with Gatsby.js

Gatsby is a React framework that allows you to create static and serverless apps. Gatsby websites are different from traditional websites because they are usually deployed on a content delivery network (CDN) and are content agnostic. In this tutorial, you will learn the basics of creating a site with Gatsby, allowing you to create static sites that are optimized for your users.

About the authors
Default avatar

Full-Stack Software Developer

I love learning new things and sharing knowledge along the way!

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
1 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

First, read our doc about what makes a PWA, a true PWA.

Next, add gatsby-plugin-manifest to your site. THis makes it possible for users to save your site to their home screen.

Now, add gatsby-plugin-offline to your project. As the name suggests, this plugin will give your site’s users the ability to still navigate to different pages, even in airplane mode, or with a poor internet connection.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more