Published 20 Oct, 2022

Making A Pwa Doesn't Have To Be Scary

Stephen Griffiths
Category Javascript
Modified : Mar 23, 2023

This article was written by Stephen Griffiths. It covers a lot of details targetting javascript, pwa, web and various other things. Stephen Griffiths is a tech enthusiast and creative writer and has been writing for a long time now. He has written around 5 posts here and has been a regular contributor to forum discussions. You can browse more details and other various blog posts and articles he has written on his personal website

Post banner

My First PWA

A Progressive Web App is a website which you can pin to your homescreen and use offline like an app. To make a website into a PWA, you have to add some metadata and a script. I'm gonna boil these down to the absolute minimum - this example is a simple single page app with just an index.html.

tl;dr You can find my app's source on Glitch at

Shopsum screenshot in Android

1. Your site must be HTTPS

Tough but true. If you can't get HTTPS set up easily on your host, consider moving to Netlify, GitHub pages, Azure Websites, or even Glitch. All of these are HTTPS by default and most are free!

2. Add a manifest.json and link to it from your HTML

Here is a minimal example file:

  "name"              : "MyApp",
  "short_name"        : "MyApp",
  "description"       : "Faith, hope, love",
  "start_url"         : "/",
  "display"           : "standalone",
  "orientation"       : "any",
  "background_color"  : "#FFF",
  "theme_color"       : "#FFF",
  "icons": [
      "src"           : "/img/android-icon-512.png",
      "sizes"         : "512x512",
      "type"          : "image/png"

You don't need an icon, but if you have one, edit the icons/src above. You can add more icons at other sizes.

The display can be:

  • fullscreen (like a game)
  • standalone (like a native app)
  • minimal-ui (has some browser controls)
  • browser (like a browser tab)

3. Add a Service Worker

Don't panic, it's easy!

If your site already has a main.js or client.js or some script that runs on the page, add this statement:

if ('serviceWorker' in navigator) {

...or else, create a new <script> tag on the page and pop that into it!

Now add a sw.js file to the project matching the location you just registered above:

const version = 'v1';

self.addEventListener('install', function(event) {
  event.waitUntil( {
      return cache.addAll([

self.addEventListener('fetch', function(event) {
  event.respondWith(caches.match(event.request).then(function(response) {
    // caches.match() always resolves
    // but in case of success response will have value
    if (response !== undefined) {
      return response;
    } else {
      return fetch(event.request).then(function (response) {
        // response may be used only once
        // we need to save clone to put one copy in cache
        // and serve second one
        let responseClone = response.clone(); (cache) {
          cache.put(event.request, responseClone);
        return response;
      }).catch(function () {
        return caches.match('/notfound.txt');

...and amend the list of files registered by the cache.addAll statement to fit your web app.

4. You did it! 👍

Your site is now offline enabled!

Offline users will only have access to the assets you listed above. So if your setup is more complex, you'll have to decide where to draw the line. The Service Worker is a robot script that decides how to get resources for the user when they're offline; Mariko did the best Service Worker explainer ever with cute illustrations to explain what it does.

If you want to make a dedicated 'Oops, you're offline' page, there are other guides for that! (See Sources below)

When you make changes to your app, you have to change the version variable to refresh clients! This can be annoying. Probably someone out there knows a better way! 😅


I drew on this SitePoint guide, Retrofit Your Website as a Progressive Web App which was pretty simple but not simple enough. MDN's Service Workers Demo was great because they gave source code of exactly what I wanted to do (so my sw.js is basically cribbed from them - here's their GitHub source)


Thanks for reading. I hope this extremely stripped-down guide was useful for you!

Meet the author

Learn more about the author of the post

Profile Picture
Stephen Griffiths

Aspiring Jesus follower; successful nerd. Find more about me on my website