Managing fallback responses Stay organized with collections Save and categorize content based on your preferences.
In certain situations, you may want a fallback response cached in case the user is offline. Implementing a fallback is an alternative to caching behaviors that strategies like network-first or stale-while-revalidate provide.
A fallback is a generic, one-size-fits-all response that's a better placeholder than what the browser would provide by default when a request fails. Some examples are:
- An alternative to the "missing image" placeholder.
- An HTML alternative to the standard "no network connection available" page.
Offline page only
If all you need to do is provide a custom offline HTML page, but nothing else, here's a baseline recipe you can follow:
import{offlineFallback}from'workbox-recipes';import{setDefaultHandler}from'workbox-routing';import{NetworkOnly}from'workbox-strategies';setDefaultHandler(newNetworkOnly());offlineFallback();
The above code usessetDefaultHandler
to use a network-only strategy as the default for all routes. It then runs theofflineFallback
recipe to serve the offline fallback in case an error occurs. The recipe assumes your offline fallback HTML file will benamedoffline.html
and served from the root of your web server.
Comprehensive fallbacks
Whenever a network failure or cache miss occurs, the caching strategies offered byworkbox-strategies
will reject consistently. This promotes the pattern of setting a global "catch" handler to deal with any failures in a single handler function, allowing you to offer different fallbacks for differentrequest.destination
values.
The following example uses thewarmStrategyCache
recipe fromworkbox-recipes
and sets a catch handler to serve items cached ahead of time in the runtime cache. However, precaching fallbacks may be a better fit for your application:
import{warmStrategyCache}from'workbox-recipes';import{setDefaultHandler,setCatchHandler}from'workbox-routing';import{CacheFirst,StaleWhileRevalidate}from'workbox-strategies';// Fallback assets to cacheconstFALLBACK_HTML_URL='/offline.html';constFALLBACK_IMAGE_URL='/images/image-not-found.jpg';constFALLBACK_STRATEGY=newCacheFirst();// Warm the runtime cache with a list of asset URLswarmStrategyCache({urls:[FALLBACK_HTML_URL,FALLBACK_IMAGE_URL],strategy:FALLBACK_STRATEGY,});// Use a stale-while-revalidate strategy to handle requests by default.setDefaultHandler(newStaleWhileRevalidate());// This "catch" handler is triggered when any of the other routes fail to// generate a response.setCatchHandler(async({request})=>{// The warmStrategyCache recipe is used to add the fallback assets ahead of// time to the runtime cache, and are served in the event of an error below.// Use `event`, `request`, and `url` to figure out how to respond, or// use request.destination to match requests for specific resource types.switch(request.destination){case'document':returnFALLBACK_STRATEGY.handle({event,request:FALLBACK_HTML_URL});case'image':returnFALLBACK_STRATEGY.handle({event,request:FALLBACK_IMAGE_URL});default:// If we don't have a fallback, return an error response.returnResponse.error();}});
In this next, fallback responses are precached usinginjectManifest
with Workbox's build tools, and served as a fallback in the event of an error with thematchPrecache
method.
import{matchPrecache,precacheAndRoute}from'workbox-precaching';import{setDefaultHandler,setCatchHandler}from'workbox-routing';import{StaleWhileRevalidate}from'workbox-strategies';// Optional: use the injectManifest mode of one of the Workbox// build tools to precache a list of URLs, including fallbacks.precacheAndRoute(self.__WB_MANIFEST);// Use a stale-while-revalidate strategy to handle requests by default.setDefaultHandler(newStaleWhileRevalidate());// This "catch" handler is triggered when any of the other routes fail to// generate a response.setCatchHandler(async({request})=>{// Fallback assets are precached when the service worker is installed, and are// served in the event of an error below. Use `event`, `request`, and `url` to// figure out how to respond, or use request.destination to match requests for// specific resource types.switch(request.destination){case'document':// FALLBACK_HTML_URL must be defined as a precached URL for this to work:returnmatchPrecache(FALLBACK_HTML_URL);case'image':// FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:returnmatchPrecache(FALLBACK_IMAGE_URL);default:// If we don't have a fallback, return an error response.returnResponse.error();}});
An example use case for the second fallback setup is if a page was cached ahead of time, but images (or other assets) requested by the page were not. The page can still be read from the cache when the user is offline, but fallback placeholders or alternate functionality can be provided if a network error occurs.
Warming the runtime cache
Workbox maintains separate caches for precaching and runtime caches, and there may be situations where you want to cache something ahead of time without relying on precaching, since updates to the precache manifest will require you to deploy an updated service worker.
To prime the runtime cache ahead of time with assets, you can do using so using thewarmStrategyCache
recipe fromworkbox-recipes
. Under the hood, this strategy callsCache.addAll
in a service worker'sinstall
event.
import{warmStrategyCache}from'workbox-recipes';import{CacheFirst}from'workbox-strategies';// This can be any strategy, CacheFirst used as an example.conststrategy=newCacheFirst();consturls=['/offline.html',];warmStrategyCache({urls,strategy});
Conclusion
Managing fallback responses for failed requests takes a bit of work, but with a bit of advance planning, you can set up your web app to provide some level of content and functionality when the user is offline.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2021-12-07 UTC.