Wilson Mar bio photo

Wilson Mar


Email me Calendar Skype call

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Responsive desktop and mobile hybrid apps that manage data offline too

US (English)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Estonian   اَلْعَرَبِيَّةُ (Egypt Arabic)   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


This page contains my notes during and after taking classes on PWA (Progressive Web Apps).

The step-by-step takes a different approach than what is covered in tutorials I took.

I would appreciate it if you could email me if you have an answer to the QUESTIONS below.

Why? (Advantages)

PWA combines the best of the web with the best of native apps.

  • Responsive on multiple screen size factors
  • Work Offline
  • App-like navigation
  • Progressive enhancement
  • Fresh, up-to-date transparently
  • Safe via TLS
  • Discoverable W3C Manifest
  • Re-engagable push notifications
  • Installable
  • Linkable - URL as entry point
  • Local Storage
  • Gamepad
  • Media capture of camera and microphone
  • Integrated payments

Sites using PWA in the wild

  • pwa.rocks is a gallery of PWA apps

  • twitter.com
  • flipboard.com

  • treebo.com (China)
  • sodapopped.com

  • getprelude.net is a simple, server less, offline-capable web app for practicing reading music. I’ve always been slow at sight reading, and this lets me plug in a MIDI piano and do drills. Uses React, Webpack, Service Workers, Web MIDI, Web Audio, VexFlow, and the Progressive Web Application paradigm. By Stephen Eisenhauer.


Udacity class


Udacity class: Intro to Progressive Web Apps by Pete LePage, Developer Advocate at Google, uses straight JavaScript without a framework library to create a weather app.

  1. Install Git and get it on your machine:

    git clone 
    https://www.github.com/wilsonmar/ud811 --depth=1

    This is forked from the original so that my commentary below would stay consistent with what is in GitHub. The original repo is:

    git clone 
  2. In Chrome, go to install and launch from the web;

    Web Server for Chrome by chromebeat.

  3. Choose folder 3-12, the completed example weather app.

  4. Click Advanced and check “Verbose logging”.

  5. Specify the port number, then click the link to view:


  6. Right-click and select Inspect for the JavaScript Console


  7. In a Finder, view folders and files of ud811.

    NOTE: Firebase has since been shut down.

    Tour of sample files

  8. View package.json. It is read by NPM (Node Program Manager) to collect dependencies.

  9. View index.html. Clients load index.html. In browsers, CSS files are loaded first and block .js files:

    <link rel="stylesheet" type="text/css" href="/styles/ud811.css">
  10. View ud811.cs. CSS files are usually stored within the styles folder. The .css files were generated from the ud811.scss file. That generation is done by gulp running the gulpfile.js before deployment. The minified min.css file is what is pushed to clients.

    App.js Shell

    Right above &LT;/body> at the bottom of the index.html are two JavaScript files in the scripts folder:

      <script src="/scripts/app.js"></script>
      <script src="/scripts/localforage-1.4.0.js"></script>
  11. View app.js – the app shell.

    • Event listeners for UI elements (butRefresh, butAdd, butAddCity, butAddCancel)

    • Methods to update/refresh the UI (toggleAddDialog, updateForecastCard)

    • Methods for dealing with the model (getForecast, updateForecasts, saveSelectedCities)

  12. Change, if you must, the injectedForecast that provides the app default data values that would be replaced by what comes back from the server.

    The time: 1453489481 is the time epoch number of seconds since January 1, 1970, which is Fri, 22 Jan 2016 19:04:41 GMT time.

    Firebase replacement by Google

    When the sample repo was created, the Firebase web service was still available. So this refered to the author’s instance:

    var weatherAPIUrlBase = 'https://publicdata-weather.firebaseio.com/';
  13. Click on the URL above. I was redirected to this Google page:


    Google’s Firebase provides what firebase.io did: Cloud Messaging, Authentication, Realtime Database, Storage, Hosting, Remote Config, Test Lab, Crash Reporting.
    Additionally, having the service in the Google Cloud give apps access to Machine Learning Functions:

    • translate the language spoken or written by the user

    • recognize image and provide an explanation about that image (like in Google Lens)

    Video: Progressive Web Apps on Firebase - Google I/O 2016

    PROTIP: There are other similar services like Firebase.

    Service Worker

  14. View service-worker.js at the root folder.

    The service-worker.js file is from Google. QUESTION: What invokes it?

  15. View manifest.json file at the root folder.

    QUESTION: What invokes it?

  16. View localforage-1.4.0.js.

    localforage-1.4.0.js is from from https://mozilla.github.io/localForage for processing Offline Storage QUESTION: What calls it?

Pluralsight course

Nik Molnar @nikmd23 nikcodes.com/wpa-fundamentals

table-of-contents Building Offline Web Apps with Service Worker

Pluralsight class: Progressive Web App Fundamentals



Google App Engine for back-end logic

Firebase redirects to HTTPS automatically from HTTP.

Android Emulator

CAUTION: Support by Apple Safari has a custom implementation. But other browsers support.

Strategy for caching vs. obtaining from network every time:

  • Cache only for images required for first render

  • Cache, then network for social media timeline data

  • Network first, then cache for game leader board data

  • Network only for inventory and prices from an ecom site

App Shell

DEMO: Weather App Shell

Local Storage


Service Workers

  1. Open Chrome browser in Incognito mode.

  2. Setup ServiceWorker in Chrome browser:


JavaScript that runs in the background to listen for and intercepts HTTPS requests, then respond to events, even when off-line.

Enables Periodic sync, geo-fencing, etc.

Register service worker

if ('serviceworker') in navigator){ // progressive enhancement.
   navigator.serviceWorker.register('/service-worker.js')  // scope limitation
          console.log('Service Worker Registered', registration);

Flow among states

pwa statuses 650x311-92k

  • Prioritize

App Mobile Manifest Packaging

  1. In index.html, add within &LT;HEAD> to tell the browser about it:

    <link rel="manifest" href="/manifest.json">

    This is defined in w3.org/TR/appmanifest

  2. In the manifest.json file:

      "name": "SodaPopped",
      "short_name": "SodaPopped",
      "start_url": "/index.html?hs=true",
      "icons": [{
     "src": "/icons/icon-128.png",
     "type": "image/png",
     "sizes": "128x128"
     "src": "/icons/icon-192.png",
     "type": "image/png",
     "sizes": "192x192"
      "background_color": "#3498DB",
      "theme_color": "#3495E",
      "orientation": "any",
      "display": "standalone",
      "dir": "ltr",
      "lang": "en-US",
      "description": "The most reliable, fast, engaging app for weather",
      "scope": "/",
      "serviceworker": {
     "src": "/path/to/sw.js",
     "scope": "/"
  3. Add in head:

    <meta name="theme-color" content="#2F3BA2">
  4. Add in home screen head for Apple Safari browser on iOS:

    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    <meta name="apple-mobile-web-app-title" content="Weather">
    <link rel="apple-touch-icon" sizes="60x60" href="apple-60.png">
    <link rel="apple-touch-icon" sizes="76x76" href="apple-76.png">
    <link rel="apple-touch-icon" sizes="120x120" href="apple-120.png">
    <link rel="apple-touch-icon" sizes="152x152" href="apple-152.png">
    <link rel="apple-touch-icon" sizes="167x167" href="apple-167.png">
    <link rel="apple-touch-icon" sizes="180x180" href="apple-180.png">

    BLAH: Apple apple-touch-startup-image

  5. Validate Manifest using the on-line tool:


  6. Cache the query string in start_url.

  7. Chrome presents “ADD TO HOME SCREEN” if there are 2 iteractions in 5 minutes. Defer the banner with onbeforeinstallprompt.

    During testing, temporarily #bypass-app-banner-engagement-checks


Chrome uses 48 dip icons for home screen and task switcher:

  • 48x48
  • 96x96
  • 144x144
  • 192x192

Chrome uses 128 dip icons for splash screen:

  • 128x128
  • 256x256
  • 384x384
  • 512x512
  1. For Apple iPhones and iPads:

    <!-- 16x16 -->
    <link rel="shortcut icon" href="https://wilsonmar.github.io/favicon.ico">
    <!-- 32x32 -->
    <link rel="shortcut icon" href="https://wilsonmar.github.io/favicon.png">
    <!-- 57x57 (precomposed) for iPhone 3GS, pre-2011 iPod Touch and older Android devices -->
    <link rel="apple-touch-icon-precomposed" href="https://wilsonmar.github.io/images/apple-touch-icon-precomposed.png">
    <!-- 72x72 (precomposed) for 1st generation iPad, iPad 2 and iPad mini -->
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="https://wilsonmar.github.io/images/apple-touch-icon-72x72-precomposed.png">
    <!-- 114x114 (precomposed) for iPhone 4, 4S, 5 and post-2011 iPod Touch -->
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="https://wilsonmar.github.io/images/apple-touch-icon-114x114-precomposed.png">
    <!-- 144x144 (precomposed) for iPad 3rd and 4th generation -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://wilsonmar.github.io/images/apple-touch-icon-144x144-precomposed.png">


  1. Android Studio - Device Bridge

  2. Update Chrome version



  3. Click port forwarding

  4. Type in the port being used by Android

    keep the page open.

Add to Home Screen

a standard approach to add to home screen.

Push Notifications

Background Sync

Offline course

push notifications

JavaScript Promises


Production Progressive Web Apps With JavaScript Frameworks (Google I/O ‘17)

Hacker News Progressive Web App (HNPWA)

Polymer using Purple functions

Lighthouse used to

Web Page Test

Twitter Lite


youmightnotneeSelect ron.com

Jake Archibald’s Off-line web app book