Skip to main content

PWA Stuffs

Progressive Web Apps need a few things to get started, and here the basics:

  1. Manifest
    1. This is an instruction sheet essentially for telling the browser what's what, and where, and to load some icons, etc.
  2. Service Worker
    1. This is the JS that will do the heavy lifting

Both files will be placed in the root of the site, or wherever you want - just make sure to update links as needed!

ICONS

No site is complete without fancy icons, so make sure you have the standard ones:

96x96 px 192x192px 512x512px SVG

MANIFEST.JSON

There are a lot of versions of this out on the net, add stuff as you need it for your own. This is just a basic example.

{
  "name": "MY SUPER COOL APP",
  "short_name": "MY APP",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#37A6D1",
  "default_locale": "en",
  "icons": [
    {
        "src": "/images/icons/favicon.svg",
        "sizes": "96x96",
        "type": "image/svg",
        "purpose": "maskable"
      },
    {
        "src": "/images/icons/favicon-96x96.png",
        "sizes": "96x96",
        "type": "image/png",
        "purpose": "maskable"
      },
    {
      "src": "/images/icons/favicon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable"
    },
    {
      "src": "/images/icons/favicon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ]
}

SW.JS

This particular one provides some basics, update, change as you need.

const CACHE_NAME = 'app-cache-v1';

// Change these as needed!
const PRECACHE_URLS = [
  '/',
  '/index.php',
  '/index.php?module=dashboard/dashboard',
  '/manifest.json',
  '/images/icons/favicon-192.png',
  '/images/icons/favicon-512.png',
  '/images/icons/apple-touch-icon.png'
];

// Pre-cache static assets
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(PRECACHE_URLS))
  );
});

// Cache-as-you-go + fallback to network
self.addEventListener('fetch', event => {
  if (event.request.method !== 'GET') return;

  event.respondWith(
    caches.match(event.request).then(cached => {
      return cached || fetch(event.request).then(networkResponse => {
        return caches.open(CACHE_NAME).then(cache => {
          if (
            event.request.url.startsWith('https://yoursite.com') &&
            !event.request.url.includes('logout') && // skip session-sensitive stuff
            !event.request.url.includes('token')     // skip tokens, auth
          ) {
            cache.put(event.request, networkResponse.clone());
          }
          return networkResponse;
        });
      });
    }).catch(() => {
      return caches.match('/offline.html'); // fallback if wanted
    })
  );
});