How to setup and configure service workers for a single page application to show an offline page

19 Views Asked by At

I have a single page application that I am registering service workers. Registration, installation, and activation works.

Fetch does not. It never fires. I'm guessing this is because the SPA uses a subdomain (api.mydomain.com) to make API calls and the service worker is registered for app.mydomain.com.

So...

  1. Is it possible to get the fetch to work for a SPA?
  2. Is it even a good idea?
  3. How should we go about showing an offline page for a SPA?

Service Worker registration

<script>
      // ServiceWorker is a progressive technology. Ignore unsupported browsers
      if ("serviceWorker" in navigator) {
        navigator.serviceWorker
          .register("./src/sw.js")
          .then(function (registration) {
            console.log("Yay, service worker registered", registration);
          })
          .catch(function (err) {
            console.log("Noooo, sevice worker didnt register", err);
          });
      }
    </script>

Service worker file

var precacheVersion = 22;
var precacheName = "precache-v" + precacheVersion;
var precacheFiles = ["/assets/offline.html"];

self.addEventListener("install", function (e) {
  console.log("[ServiceWorker] Installed");
  self.skipWaiting();

  e.waitUntil(
    caches.open(precacheName).then(function (cache) {
      console.log("[ServiceWorker] Precaching files");
      return cache.addAll(precacheFiles);
    })
  ); // end e.waitUntil
});

self.addEventListener("activate", function (e) {
  console.log("[ServiceWorker] Activated");

  e.waitUntil(
    caches.keys().then(function (cacheNames) {
      return Promise.all(
        cacheNames.map(function (thisCacheName) {
          if (
            thisCacheName.indexOf("precache") !== -1 &&
            thisCacheName !== precacheName
          ) {
            console.log(
              "[ServiceWorker] Removing cached files from old cache - ",
              thisCacheName
            );
            return caches.delete(thisCacheName);
          }
        })
      );
    })
  ); // end e.waitUntil
});
self.addEventListener("fetch", function (e) {
  console.log("[ServiceWorker] Fetch event for ");
  e.respondWith(
    caches.match(e.request).then(function (cacheResponse) {
      if (cacheResponse) {
        console.log("Found in cache!");
        return cacheResponse;
      }
      return fetch(e.request)
        .then(function (fetchResponse) {
          return fetchResponse;
        })
        .catch(function (err) {
          var isHTMLPage =
            e.request.method == "GET" &&
            e.request.headers.get("accept").includes("text/html");
          if (isHTMLPage) {
            return caches.match("/assets/offline.html");
          }
        });
    })
  );
});
0

There are 0 best solutions below