Very Simple PWA Example (A Step-By-Step Guide)

Welcome to a tutorial on how to create a very simple Progressive Web Application. Just heard of this “PWA” thing and wondering how to get started? Well, let us walk through a barebones PWA example in this guide – Feel free to use it as a template in your own project. Read on!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Basic PWA Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

 

BAREBONES PWA

All right, let us now get into the step-by-step example of creating a barebones PWA.

 

STEP 1) THE HTML

1-index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- (A) TITLE + CHARSET + DESCRIPTION -->
    <title>Barebones PWA</title>
    <meta charset="utf-8">
    <meta name="description" content="A barebones PWA page">
 
    <!-- (B) VIEWPORT (ALLOW ZOOM IN, NOT OUT) -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.5">
 
    <!-- (C) WEB APP MANIFEST -->
    <!-- https://web.dev/add-manifest/ -->
    <link rel="manifest" href="4-manifest.json">
 
    <!-- (D) GOOD OLD FAVICON -->
    <link rel="icon" href="favicon.png" type="image/png">
 
    <!-- (E) ANDROID/CHROME -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="theme-color" content="white">
 
    <!-- (F) IOS APP ICON + MOBILE SAFARI -->
    <link rel="apple-touch-icon" href="icon-512.png">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="Hello World">
 
    <!-- (G) WINDOWS -->
    <meta name="msapplication-TileImage" content="icon-512.png">
    <meta name="msapplication-TileColor" content="#ffffff">
 
    <!-- (H) STYLESHEET + JAVASCRIPT -->
    <link rel="stylesheet" href="2-style.css">
    <script defer src="3a-main.js"></script>
  </head>
  <body>
    It Works!
  </body>
</html>

As you can see, this is just a “normal” HTML page, except that it has a ton of meta tags. Keep calm and let’s go through them.

  • (A) The usual title, character set, description.
  • (B) HTML viewport. This is set to allow zoom in, not out. Read my other tutorial on disabling pinch-zoom to learn more.
  • (C) The web app manifest, an important part of a PWA. A JSON file to define the app name, description, icons, etc…
  • (D To G)  The irritating part. Homescreen icons and browser-specific theme colors. Everyone has their own set of meta tags, these are the common ones that I gathered from the Internet.
  • (H) The stylesheet and Javascript.

P.S. I find it a waste of time trying to please everyone on their custom icon sizes. One simple way is to use 64X64 for the favicon, and feed a massive 512X512 to everyone else.

 

 

STEP 2) THE CSS

2-style.css
* { font-family: arial, sans-serif; }
body {
  background: #000;
  color: #fff;
}

Nothing to see here, just a few lines of dummy CSS.

 

STEP 3) JAVASCRIPT (SERVICE WORKER)

MAIN SCRIPT

3a-main.js
if ("serviceWorker" in navigator) {
  navigator.serviceWorker.register("3b-sw.js");
}

This should be the script that runs when the HTML is done loading. In this example, we will register a service worker. If you do not know what a service worker is, I shall leave links in the extras section below.

 

SERVICE WORKER CACHING

3b-sw.js
// (A) FILES TO CACHE
const cName = "demo-pwa",
cFiles = [
  "1-index.html",
  "2-style.css",
  "3a-main.js"
];

// (B) CREATE/INSTALL CACHE
self.addEventListener("install", (evt) => {
  evt.waitUntil(
    caches.open(cName)
    .then((cache) => { return cache.addAll(cFiles); })
    .catch((err) => { console.error(err) })
  );
});
 
// (C) CACHE STRATEGY
self.addEventListener("fetch", (evt) => {
  // (C1) LOAD FROM CACHE FIRST, FALLBACK TO NETWORK IF NOT FOUND
  event.respondWith(
    caches.match(evt.request)
    .then((res) => { return res || fetch(evt.request); })
  );
 
  /* (C2) LOAD WITH NETWORK FIRST, FALLBACK TO CACHE IF OFFLINE
  evt.respondWith(
    fetch(evt.request)
     .catch(() => { return caches.match(evt.request); })
  );*/
});

What is the whole point of this “service worker”? Offline caching. Yes, another huge part of PWA is being able to function even when the user is offline. A quick summary of what is happening here:

  1. Define the name of the storage cache and a list of files to save into the cache. Take note, this is NOT the browser cache, but a persistent app cache.
  2. Create the cache, save the specified files.
  3. “Hijack” the browsers fetch calls. We can either:
    • (C1) Try to load the requested file from the cache first. Fallback and load from the network if the file is not in the cache.
    • (C2) Load from the network first, then fallback to a cached copy if the user is offline.

I shall leave a link below again, if you want to learn more about offline caching.

 

 

STEP 4) WEB APP MANIFEST

4-manifest.json
{
  "short_name": "DPWA",
  "name": "Demo PWA",
  "icons": [{
     "src": "favicon.png",
     "sizes": "64x64",
     "type": "image/png"
  }, {
    "src": "icon-180.png",
    "sizes": "180x180",
    "type": "image/png"
  }],
  "start_url": "1-index.html",
  "scope": "/",
  "background_color": "white",
  "theme_color": "white",
  "display": "standalone"
}

Remember the manifest from step 1? This is how it may look like, read more on web dev for the full list of manifest properties.

 

DEPLOY & TEST

That’s all. Launch http://localhost/1-index.html in your browser and it should offer an option to install the PWA.

Go ahead and install it. The icon should appear on your home screen or desktop. If you open chrome://apps OR opera://apps OR edge://apps the icon should be right there as well.

P.S. Deleting the icon on your home screen or desktop will not “uninstall” the PWA. You need to do it on the browser apps page itself.

 

 

USEFUL BITS & LINKS

That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.

 

WHAT ARE THE REQUIREMENTS FOR A PWA?

Just what are the exact requirements to be considered a PWA? It seems like there’s no straight answer at the time of writing, but I will point to 3 principles on web dev:

  • Capable: Can do all kinds of funky things. Video, audio, save data, send data, peer-to-peer, etc…
  • Reliable: Has fallback for old browsers, works even when offline.
  • Installable: As above.

So yes, we have pretty much covered “reliable” and “installable” in this quick guide. It is up to you to develop your own “capable”.

 

SECURE ORIGIN

A gentle reminder – You must use https:// for “install app” to show up, and to register service workers. http://localhost is an exception for development and testing.

 

COMPATIBILITY CHECKS

Works on all modern “Grade A” browsers.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *