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...
- Is it possible to get the fetch to work for a SPA?
- Is it even a good idea?
- 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");
}
});
})
);
});