Search code examples
javascriptservice-workerworkbox

How to use Workbox setDefaultHandler


I'm switching from sw-toolbox to Workbox and I can't figure out how to use setDefaultHandler().

If I try (as stated in the documentation linked above):

workboxSW.router.setDefaultHandler({
    handler: new workbox.runtimeCaching.CacheFirst()
});

I get an error that runtimeCaching is undefined:

Uncaught ReferenceError: router is not defined

So.. how do I use it and configure it in a way similar to how I could configure sw-toolbox:

toolbox.options.cache = {
    name: "default",
    maxEntries: 128,
    maxAgeSeconds: (60*60*24), // 24hrs
};
toolbox.router.default = toolbox.cacheFirst;

I would like to be able to do something like this:

workboxSW.router.setDefaultHandler({
    handler: workboxSW.strategies.cacheFirst({
        cacheName: 'default',
        cacheExpiration: {
            maxEntries: 128,
        },
        cacheableResponse: {statuses: [0, 200]},
    })
});

..which doesn't throw compile errors but when I use it I get this:

Uncaught (in promise) TypeError: Request method 'POST' is unsupported

..and my Cache Storage for 'default' remains empty..?


Solution

  • Since my edits for Jeff's first solution were rejected I'll just go ahead and submit an answer myself.

    Jeff's sample came close. He suggested:

    You could check for the request type in the default handler, and only apply the cache-first strategy to GET requests:

    workboxSW.router.setDefaultHandler({
      handler: (args) => {
        if (args.event.request.method === 'GET') {
          return workboxSW.strategies.cacheFirst(args);
        }
        return fetch(args.event.request);
      },
    });
    

    It's the right approach but the example code he provided didn't work. The handler argument needs a handler, not a strategy. Luckily, strategies have exactly one (public) method, called "handle".

    So I modified his code a little; First, I create a strategy called defaultStrategy with all the options I need. Then, in the setDefaultHandler call, I return defaultStrategy.handle(args) instead of the CacheFirst constructor. That's it!

    // Register 'default'
    var defaultStrategy = workboxSW.strategies.cacheFirst({
        cacheName: "default",
        cacheExpiration: {
            maxEntries: 128,
            // more options..
        },
        cacheableResponse: {statuses: [0, 200]},
    });
    workboxSW.router.setDefaultHandler({
        handler: (args) => {
            if (args.event.request.method === 'GET') {
                return defaultStrategy.handle(args);
            }
            return fetch(args.event.request);
        },
    });
    

    UPDATE: Workbox v3

    As I pointed out in the comments below, the above code doesn't work with Workbox v3. Use this instead:

    // Register 'default'
    var defaultStrategy = workbox.strategies.cacheFirst ({
        cacheName: "your.cache.name",
        plugins: [
            new workbox.expiration.Plugin({
                maxEntries: 128,
                maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
                purgeOnQuotaError: true, // Opt-in to automatic cleanup
            }),
            new workbox.cacheableResponse.Plugin({
                statuses: [0, 200] // for opague requests
            }),
        ],
    });
    workbox.routing.setDefaultHandler(
        (args) => {
            if (args.event.request.method === 'GET') {
                return defaultStrategy.handle(args); // use default strategy
            }
            return fetch(args.event.request);
        }
    );