Welcome back! This is the third and final part of a tutorial where we go through and build a PWA from scratch that utilizes a powerful architecture pattern called the JAMStack. You can find the blogpost covering part 1 here and part 2 here. I’d suggest reading through them first as we’ll be jumping straight into from where we left off.

A note on part 2: I made a mistake in ./src/pages/new.js. Since we’ve set the firebase database rules to only allow authenticated users to write to the database, we have to be sure a uid exists before creating a new poll. Here’s a link to the updated gist file. Be sure your code signs the user in anonymously before creating the poll.


The manifest file is the standardized place to declare metadata about your site. It’s required in order to utilize features like prompting users to save the app. to their home screen and custom splash screens when launching the web app. Features like this have the goal of making the user experience indistinguishable from a native application experience.

Firstly, let’s generate some icons for our site’s favicon at different sizes using a handy online tool at realfavicongenerator.net. Save the image found here to your computer and upload it to realfavicongenerator.net. Once it’s uploaded, hit Generate your Favicons and HTML code. Download the provided zip file of all the icon sizes for the different devices. Then create a new directory in the static directory called favicons and place the contents of the zip file in there. Delete the site.webmanifest and the browserconfig.xml files. The webmanifest file will be generated by another gatsby plugin called gatsby-plugin-manifest which we’ll add in a moment.

For the browsers that don’t support manifest files, let’s add the site’s metadata in the head of the html as well. To accomplish this, we can edit the props passed to the React-Helmet component in our ./src/layouts/index.js file.

Notice that we’ve used withPrefix method from gatsby-link. This is required whenever we reference something in the static directory from our source code. You can read more about withPrefix and the static directory here.

Services workers

To enable an offline experience for our application we’ll need to make use of service workers. A service worker is a script that runs on a separate thread than that of your website that can be utilized for several technologies that previously weren’t possible on the web. It remains active even when the user doesn’t have the site open and enables us web developers to implement tools and techniques like push notification, background sync, offline support, intercepting fetch requests, and more. In our application, we’ll use a service worker to cache our html and javascript files so that when a user visits our site with a connection, the site’s assets get saved to the user’s local browser cache. Upon subsequent visits, that cache will be used as opposed to relying on the network for those assets. There are several caching strategies, but in this tutorial we’ll use the cache and update strategy that comes default with the plugin.

Let’s install the gatsby-plugin-manifest and gatsby-plugin-offline plugins and update our gatsby-config.js file to make use of them:

npm install gatsby-plugin-manifest gatsby-plugin-offline

After deploying the updated code and running another Lighthouse test, let’s juxtaposition the new results with the results from part 2 of the series:

The new report can be found here. Your results may vary. The primary reason behind our performance score not being higher is because of the firebase sdk. It is quite large in size.

The site’s performance score increased from 70 to 83, the PWA score increased from 36 to 91, and best practices increased from 81 to a perfect 100. All that just by adding two plugins. In my opinion, that’s pretty impressive considering the minimal amount of work put in on our part.

The only failed PWA audit has to do with the fact the site doesn’t redirect http traffic to https as service workers don’t work without https. Unfortunately, Netlify currently doesn’t offer an option to enable this when the site is hosted on a Netlify subdomain. However, you could enable https redirect by adding a custom domain, which, like many of the other awesome features offered, is free (you still got to buy the domain, of course).

Another sweet benefit of PWAs is the ability to save to a user’s home screen. Since we’ve added a web app manifest file and our site can be access via https, when users interact with the application long enough, they’ll be prompted to save it to their home screen. Again, the goal with these sorts of features is to close the gap between web apps. and native apps.

Add to home screen doesn’t have cross-browser support. Windows and iOS devices don’t support this spec as of yet.

Wrapping up

That’s all folks! We’ve built a progressive web application that utilizes the JAMStack pattern of building websites. We’ve covered a lot and I’m quite pleased with the results considering what we’ve accomplished. To summarize a few key points:

  • the performance of our site is fantastic thanks to Netlify’s global CDN and Gatsby’s utilization of the PRPL pattern.
  • you can expect the great results when it comes to SEO thanks to Gatsby.js and its sick plugin ecosystem.
  • the site is still accessible even when users are offline or have shotty connections.
  • despite the whole application being static, it has a backend and authentication working.

There’s so much more we haven’t covered when it comes to Gatsby.js. I encourage you all look into it a bit more and contribute to the awesome Gatsby.js ecosystem.

With that said, this concludes the series. Tell me what you thought. I hope you all enjoyed following along as much as I enjoyed writing these!

If you have any issues or would like to see the completed code please visit our repository here.

Be sure to follow us for more blogs every Monday and Tuesday!

John Korzhuk is a software developer and proud Unicorn. He specializes in full-stack javascript, React.js, and web development. Outside of work his interests include gaming, esports, and learning about anything that he finds interesting. You can find on twitter @johnkorzhuk.

Want to build magical experiences together? Contact us!

E-mail: social@unicorngency.com

Twitter: @UnicornHQ

Website: http://www.unicornagency.com