Search code examples
service-workerprogressive-web-apps

Service worker installs via localhost, but fails when deployed to GitHub pages


I am working on a PWA and I have installed and activated a service worker on my site. It works perfectly well while testing on local server but when I ship my code live, it fails.

This is my SW:

const cacheName = 'v1';
const cacheFiles = [
    '/',
    '/css/styles.css',
    '/images/test1.png',
    '/images/test2.png',
    '/js/app.js',
    '/js/sw-registration.js'
]

// Install event
self.addEventListener('install', function(event) {
    console.log("SW installed");
    event.waitUntil(
        caches.open(cacheName)
        .then(function(cache){
            console.log('SW caching cachefiles');
            return cache.addAll(cacheFiles);
        })
    )
});

// Activate event
self.addEventListener('activate', function(event) {
    console.log("SW activated");
    event.waitUntil(
        caches.keys()
        .then(function(cacheNames){
            return Promise.all(cacheNames.map(function(thisCacheName){
                if(thisCacheName !== cacheName){
                    console.log('SW Removing cached files from', thisCacheName);
                    return caches.delete(thisCacheName);
                }
            }))
        })
    )
});

// Fetch event
self.addEventListener('fetch', function(event) {
    console.log("SW fetching", event.request.url);
    event.respondWith(
        caches.match(event.request)
        .then(function(response){
            console.log('Fetching new files');
            return response || fetch(event.request);
        })
    );
});

This is the error I'm getting:

Uncaught (in promise) TypeError: Request failed     (sw.js:1)

I don't understand why it fails to cache my files online (github pages) when it works locally. Can someone help me understand?

Thank you.

EDIT: I tried to deploy the site via Netlify and it works there. So it has to be something to do with Github pages. I would still like to know what it is, if anyone can shed any light.


Solution

  • As mentioned in Service Worker caches locally but fails online, when deploying to gh-pages, your web app's content will normally be accessed from a subpath, not in the top-level path, for the domain.

    For instance, if your files are in the gh-pages branch of https://github.com/<user>/<repo>, then your web content can be accessed from https://<user>.github.io/<repo>/.

    All of the URLs in your cacheFiles array are prefixed with /, which isn't what you want, given that all of your content is accessible under /<repo>/. For instance, / is interpreted as https://<user>.github.io/, which is different from https://<user>.github.io/<repo>/.

    The solution to your problem, which will lead to a configuration that works regardless of what the base URL is for your hosting environment, is to prepend each of your URLs with ./ rather than /. For instance:

    const cacheFiles = [
      './',
      './css/styles.css',
      // etc.
    ];
    

    The ./ means that the URL is relative, with the location of the service worker file used as the base. Your service worker file will be deployed under https://<user>.github.io/<repo>/, so that will end up being the correct base URL to use for the rest of your content as well.