NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #3317 most downloaded on npm
A service worker helper library to route request URLs to handlers.
Last release 5 months ago
04 May 2026
Release timing varies
gaps range from 2 weeks to 13 months
Most releases are documented
notes for 53 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
9 years old
98 releases · first in 2017
migrate rollup v4 and plugins by @AJIb63PT in https://github.com/GoogleChrome/workbox/pull/3446
actions/cache to v5 by @swissspidy in https://github.com/GoogleChrome/workbox/pull/3491npm audit fix) by @swissspidy in https://github.com/GoogleChrome/workbox/pull/3510Full Changelog: https://github.com/GoogleChrome/workbox/compare/v7.4.0...v7.4.1
One column per quarter.
v7.4.0 - Critical dependency updates.
v7.4.0
v7.3.0 - Critical dependency updates.
v7.3.0
Updating dependencies with critical vulnerabilities, plus some other dependencies maintenance
Full Changelog: https://github.com/GoogleChrome/workbox/compare/v7.0.0...v7.1.0
Minimum required version Node 16
⚠️ Breaking changes
Nothing published for this version
updating typescript version and types by @tropicadri in https://github.com/GoogleChrome/workbox/pull/3181
Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.5.4...v6.6.0
Webpack plugin can be extended and subclasses can access the config property [#3056]
config property [#3056]workbox-precaching during a fall back to the network, if the request's mode is no-cors, integrity will not be used and the cache entry will not be repaired. [#3099]idb and selenium-assitant versionsFull Changelog: https://github.com/GoogleChrome/workbox/compare/v6.5.3...v6.5.4
Update minimist to a non-vulnerable version. by @lgarron in https://github.com/GoogleChrome/workbox/pull/3053
minimist to a non-vulnerable version. by @lgarron in https://github.com/GoogleChrome/workbox/pull/3053Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.5.2...v6.5.3
Workbox v6.5.2 includes a number of improvements to the TypeScript documentation and exported types, which should in turn improve the generated docume
Workbox v6.5.2 includes a number of improvements to the TypeScript documentation and exported types, which should in turn improve the generated documentation.
A full changelog is available at https://github.com/GoogleChrome/workbox/compare/v6.5.1...v6.5.2
The Workbox v6.5.1 release includes a few changes related to our TypeScript interfaces and documentation.
The Workbox v6.5.1 release includes a few changes related to our TypeScript interfaces and documentation.
A full changelog is available at https://github.com/GoogleChrome/workbox/compare/v6.5.0...v6.5.1
@examples of using our build tools have been added to the TSDocs for workbox-build and workbox-webpack-plugin. [#3038]generateSW(), injectManifest(), and getManifest() methods in workbox-build has been updated from unknown to an appropriate actual type specific to each method. This should lead to better TSDoc generation and type inferences for developers. As this takes what was previously only a runtime check and moves it to a compile-time check, we believe that it should be functionally equivalent to prior releases, but if you run into problems, please let us know by opening an issue. [#3037]default export to workbox-webpack-plugin. [#3036]Removed the dependency on the deprecated source-map-url package. [#3031]
The Workbox v6.5.0 release includes a number of smaller fixes, as well as a major rewrite of the workbox-webpack-plugin to TypeScript.
A full changelog is available at https://github.com/GoogleChrome/workbox/compare/v6.4.2...v6.5.0
workbox-webpack-plugin has been rewritten in TypeScript, and has public TypeScript definitions for its interfaces published as part of this release. We do not anticipate any changes in the underlying functionality as part of this rewrite. [#2882]forceSyncFallback parameter has been added to workbox-background-sync, without changing the default behavior. When forceSyncFallback is explicitly set to true, workbox-background-sync will always attempt to replay queued requests when the service worker starts up and never rely on the sync event listener. Most developers will not need this behavior, but it can be useful when targeting environments that have a non-functional Background Sync implementation, like some Electron runtimes. [#3020]workbox-streams. [#3001]workbox-background-sync which could lead to errors when run through with certain aggressive minifiers. [#3012]waitUntil() was added to the StaleWhileRevalidate strategy, ensuring that it works properly with navigation preload responses. [#3015]source-map-url package. [#3031]Thank you to @roikoren755 for their contributions to the workbox-webpack-plugin TypeScript migration!
The Workbox v6.4.2 release fixes a few issues:
The Workbox v6.4.2 release fixes a few issues:
@apideck/better-ajv-errors to ^0.3.1 by @wopian in https://github.com/GoogleChrome/workbox/pull/2988ExpirationPlugin docs by @mungojam in https://github.com/GoogleChrome/workbox/pull/2987workbox wizard --injectManifest by @jeffposnick in https://github.com/GoogleChrome/workbox/pull/2992Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.4.1...v6.4.2
The Workbox v6.4.1 release fixes a few issues:
The Workbox v6.4.1 release fixes a few issues:
@apideck/better-ajv-errors has been updated, which in turn addresses a security issue in one of its dependencies. [#2977]preloadResponse was incorrect, and has been fixed to reflect the previous definition that used to be provided by the TypeScript standard library. [#2975]request.url into account in StrategyHandler.getCacheKey(). This ensures if a custom strategy overrides the Strategy._handle() method and performs multiple cache operations on different URLs, the cache key is properly calculated for each distinct URL. [#2973]We upgraded @surma/rollup-plugin-off-main to patch a vulnerability from the dependency. [#2962]
Workbox v6.4.0 includes:
size(). [#2941]injectManifest. It returns now returns a warning and continues with execution. [#2959]To our new contributors in this version: @StephanBijzitter and @fuzail-ahmed!
Workbox v6.3.0 includes a couple of bug fixes and several new features.
Workbox v6.3.0 includes a couple of bug fixes and several new features.
Although unexpected, there are edge cases where the precache might not be in an inconsistent state, most likely due to a developer manually deleting something in DevTools.
When this happens, workbox-precaching defaults to falling-back to using a network response (assuming the device is online) when there's a precaching miss. Up until now, workbox-precaching hasn't attempting to use this network response to repopulate the precache, because there are no guarantees that the network response corresponds to the version of the asset specified in the precache manifest.
However, if the precache entry includes an integrity property, then subresource integrity guarantees that the response does correspond to the same version of the asset in the manifest. So it should be safe to "repair" the cache with that response. [#2921]
This small change to the way Workbox writes to IndexedDB should lead to slightly better performance, without any appreciable downsides. [#2934]
BroadcastCacheUpdate uses postMessage() to notify all open tabs controlled by the current service worker about a cache update. This default behavior is not changing.
Setting notifyAllClients: false when configuring BroadcastCacheUpdate and the associated plugin will result in postMessage() only communicating the update to the specific window client that triggered the fetch request which resulted in the cache update. [#2920]
This enhancement makes it easier to use TypeScript to write workbox-window event handlers. [#2919]
The presence of Vary: headers on a cached Response can make it difficult to properly match and delete cache entries. To make it clearer to developers when this is happening, the development builds of Workbox will now log a message to the console when a Response that's being cached includes a Vary: header. [#2916]
chokidar dependency, for better node compatibility and to eliminate security warnings. [#2913]PrecacheCacheKeyPlugin. [#2914]Passing in functions for onSync and handler in generateSW's runtimeCaching should not fail validation. [#2911]
onSync and handler in generateSW's runtimeCaching should not fail validation. [#2911]Move @types/trusted-types to dependencies of workbox-window [#2909]
@types/trusted-types to dependencies of workbox-window [#2909]Workbox v6.2.2 fixes a few bugs introduced in the v6.2.0 release.
Workbox v6.2.2 fixes a few bugs introduced in the v6.2.0 release.
Validation fix for plugin functions passed to runtimeCaching in the build tools. [#2901]
Ensure that our tsc configuration transpiles newer language features down to the ES2017 target level. [#2902]
Update to our lerna configuration to use the --exact tag when publishing to npm, to ensure that all the mutual dependencies in the monorepo use exact version matches, and not ^ versions. [#2904]
Fix WorkboxPlugins schema validation by @jeffposnick in https://github.com/GoogleChrome/workbox/pull/2903
Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.2.0...v6.2.1
Our intention is not to include any breaking changes in v6.2.0, and we've made an effort to maintain the same public interfaces and general behaviors…
Workbox v6.2.0 includes a number of bug fixes and internal refactoring described below.
Our intention is not to include any breaking changes in v6.2.0, and we've made an effort to maintain the same public interfaces and general behaviors while rewriting some of Workbox's internals.
The workbox-build module has been rewritten in TypeScript, following the earlier migration of the workbox-cli module. (workbox-webpack-plugin has not yet been migrated.) Developers who use workbox-build from their own TypeScript code should benefit from the official, accurate type definitions that are now published alongside workbox-build. [#2867]
As part of this change, workbox-build now uses the TypeScript definitions as the source of truth when validating the configuration options developers provide. Previously, joi was used for validation with its own set of schema, and this would sometimes lead to mismatches between what the validation logic thought was okay and what the code actually expected. Developers who inspect the validation errors returned by workbox-build will likely see different error strings in v6.2.0. We expect that moving forward, using TypeScript as the source of truth will lead to fewer of those mismatches.This change applies to both workbox-cli and workbox-webpack-plugin, as well, which rely on workbox-build under the hood.
Another refactoring is the replacement of our previous custom IndexedDB logic with the idb library. No developer-visible changes are expected due to this migration. [#2838]
Following this change, worbox-window's controlling event is fired each time the underlying oncontrollerchange event happens. Multiple controlling events can occur on a long-lived page in which multiple service worker updates take place. isExternal: true will be set when the service worker that takes control is "external," which will always be the case for multiple updates.
Previously, controlling would only be fired once per lifetime of the page, which does not match the documented behavior. This change is considered a bug fix to match the expected behavior, and developers are encouraged to test their logic to ensure that they were not relying on the previous, buggy behavior. [#2817]
Developers who have opted-in to the CSP policy "require-trusted-types-for 'script'" and who are using TypeScript would have previously had trouble using TrustedScriptURLs in workbox-window. This release improves that support. [#2872]
Setting rangeRequests: true inside of a runtimeCaching configuration entry will add the RangeRequestsPlugin to the service worker generated by Workbox's build tools. [#2871]
HandlerDidErrorCallbackParam type definition is now exported alongside the other relevant TypeScript types. [#2886]webpack's eval-cheap-source-map is used along with the InjectManifest plugin. [#2847]ports was missing on the WorkboxMessageEvent. It's been added, mirroring the value of the underlying MessageEvent, when used in an onmessage handler. [#2874]
The WorkboxEventMap type definition is now exported alongside the other relevant TypeScript types. [#2870]
Thank you @rockwalrus for contributing a PR [#2857] that went into this release!
fixing binding issues with idb upgrade callback by @tropicadri in https://github.com/GoogleChrome/workbox/pull/2896
Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.2.0-alpha.0...v6.2.0-alpha.2
fixing binding issues with idb upgrade callback by @tropicadri in https://github.com/GoogleChrome/workbox/pull/2896
Full Changelog: https://github.com/GoogleChrome/workbox/compare/v6.2.0-alpha.0...v6.2.0-alpha.1
Our intention is not to include any breaking changes in v6.2.0, and we've made an effort to maintain the same public interfaces and general behaviors…
Workbox v6.2.0-alpha.0 is the first pre-release version of Workbox v6.2.0. It includes a number of bug fixes and internal refactorings described below.
Our intention is not to include any breaking changes in v6.2.0, and we've made an effort to maintain the same public interfaces and general behaviors while rewriting some of Workbox's internals. However, since a significant amount of refactoring did take place, we wanted to make it available as a pre-release initially, and give developers a chance to test it before we tag it as the latest release in npm.
The workbox-build module has been rewritten in TypeScript, following the earlier migration of the workbox-cli module. (workbox-webpack-plugin has not yet been migrated.) Developers who use workbox-build from their own TypeScript code should benefit from the official, accurate type definitions that are now published alongside workbox-build. [#2867]
As part of this change, workbox-build now uses the TypeScript definitions as the source of truth when validating the configuration options developers provide. Previously, joi was used for validation with its own set of schema, and this would sometimes lead to mismatches between what the validation logic thought was okay and what the code actually expected. Developers who inspect the validation errors returned by workbox-build will likely see different error strings in v6.2.0. We expect that moving forward, using TypeScript as the source of truth will lead to fewer of those mismatches.This change applies to both workbox-cli and workbox-webpack-plugin, as well, which rely on workbox-build under the hood.
Another refactoring is the replacement of our previous custom IndexedDB logic with the idb library. No developer-visible changes are expected due to this migration. [#2838]
Following this change, worbox-window's controlling event is fired each time the underlying oncontrollerchange event happens. Multiple controlling events can occur on a long-lived page in which multiple service worker updates take place. isExternal: true will be set when the service worker that takes control is "external," which will always be the case for multiple updates.
Previously, controlling would only be fired once per lifetime of the page, which does not match the documented behavior. This change is considered a bug fix to match the expected behavior, and developers are encouraged to test their logic to ensure that they were not relying on the previous, buggy behavior. [#2817]
Developers who have opted-in to the CSP policy "require-trusted-types-for 'script'" and who are using TypeScript would have previously had trouble using TrustedScriptURLs in workbox-window. This release improves that support. [#2872]
Setting rangeRequests: true inside of a runtimeCaching configuration entry will add the RangeRequestsPlugin to the service worker generated by Workbox's build tools. [#2871]
HandlerDidErrorCallbackParam type definition is now exported alongside the other relevant TypeScript types. [#2886]webpack's eval-cheap-source-map is used along with the InjectManifest plugin. [#2847]ports was missing on the WorkboxMessageEvent. It's been added, mirroring the value of the underlying MessageEvent, when used in an onmessage handler. [#2874]
The WorkboxEventMap type definition is now exported alongside the other relevant TypeScript types. [#2870]
Thank you @rockwalrus for contributing a PR [#2857] that went into this release!
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
Workbox v6.1.5 includes fixes in workbox-cli, workbox-window and workbox-webpack-plugin. Also, the rollup and @rollup/plugin-node-resolve dependencies
Workbox v6.1.5 includes fixes in workbox-cli, workbox-window and workbox-webpack-plugin. Also, the rollup and @rollup/plugin-node-resolve dependencies were updated.
(There was no v6.1.3 or v6.1.4 release.)
In the configuration file generated by workbox wizard the regex for ignoreURLParametersMatching are now serialized correctly, as before they were being serialized as strings and that was causing errors. [#2796]
Added support for external controlling events. The controlling event is now dispatched whether it originated in the current or external service worker. Developers can check the isExternal flag to distinguish between the two. [#2786]
Fix to push an Error object to compilation.warnings instead of strings, since pushing strings causes the warnings to not be bubbled up correctly. See [#2790]
Thank you @jcabak for contributing documentation updates [#2808]!
Nothing published for this version
Workbox v6.1.2 includes several fixes to the workbox-cli's wizard mode, and removes some potentially confusing logging.
Workbox v6.1.2 includes several fixes to the workbox-cli's wizard mode, and removes some potentially confusing logging.
workbox-build was used, due to an update to the @rollup/plugin-replace plugin that it uses. The underlying issue raised in the warning message has been addressed. [#2772]Previously, the wizard question flow would not give developers the opportunity to specify a value to override the default ignoreURLParametersMatching setting. The wizard now provides some context and explicitly asks about overriding this value. [#2763]
There were two issues fixed in the wizard related to entering the globDirectory value: the separator characters, --------, were inadvertently selectable, and additionally, the logic was buggy when a manual directory name was entered. Both of these issues are fixed. [#2766]
Special thanks to @ognjenjevremovic for contributing the two workbox-cli PRs that went into this release!
Workbox v6.1.1 includes a bug fix for the NetworkFirst strategy, as well as some documentation and TypeScript fixes.
Workbox v6.1.1 includes a bug fix for the NetworkFirst strategy, as well as some documentation and TypeScript fixes.
The NetworkFirst strategy uses two promises: one for the network request, and one is the optional networkTimeoutSeconds option is set. If the network request succeeds, then the timeout promise's timer is canceled. However, the strategy previously attempted to wait until both promises resolve before the handler resolves. This meant that, if the network request succeeds before the timeout, the strategy's over handler promise would not properly resolve.
See #2744
Special thanks to @joshkel for both bringing that NetworkFirst issue to our attention, as well as contributing the code for the fix!
Workbox v6.1.0 includes a number of new features, as well as an important fix for a bug that could have affected workbox-precaching behavior in earlie
Workbox v6.1.0 includes a number of new features, as well as an important fix for a bug that could have affected workbox-precaching behavior in earlier v6 releases.
The setCatchHandler() method on a Router allows you to configure "fallback" logic if any handler invoked by that Router returns an error. It can be awkward to use, however, if you have many different Routes registered for the same Router, and you would prefer that the fallback logic only be invoked when one or two particular Route handlers fail.
Starting in this release, each individual Route object has a setCatchHandler() method, allowing you to add fallback logic just to that Route, without affecting any other Routes. To use this method, make sure you explicitly construct a Route first, and then pass that Route to the (overloaded) registerRoute() method:
import {Route, registerRoute} from 'workbox-routing';
import {NetworkOnly, StaleWhileRevalidate} from 'workbox-strategies';
const navigationRoute = new Route(
({event, request, url}) => request.mode === 'navigate',
new NetworkOnly()
);
navigationRoute.setCatchHandler(
({event, request, url}) => {
// Do something to generate a fallback response,
// e.g. read a HTML document from the cache.
}
);
registerRoute(navigationRoute);
// This route, created implicitly via an overloaded registerRoute()
// method, won't have the catch handler applied.
registerRoute(
({event, request, url}) => request.destination === 'image',
new StaleWhileRevalidate()
);
See #2699
The workbox-recipes module has been extended with a few new features:
warmStrategyCache, which takes an array of paths and a Workbox strategy and warms that strategy's cache with those paths at service worker install time.warmCache option to page, image, and static resource recipes to allow users to warm those caches.plugins option to page, image, and static resource recipes to allow users to pass additional plugins to those recipes, allowing a user, for instance, to add a URL normalization plugin to the page recipe.The workbox-recipes documentation has more information and examples.
See #2718
The expected behavior for workbox-precaching is that all URLs listed in the precache manifest need to be considered "cacheable" in order for service worker installation to succeed. By default, workbox-precaching considers any response with a status code less than 400 as being cacheable (including opaque responses, which have a status code of 0). Developers who need to customize this behavior can pass a cacheWillUpdate plugin to workbox-precaching, and use that logic to determine whether or not a response should be precached during installation.
Two bugs were introduced in the Workbox v6.0.0 release:
The default criteria, in which any response with a status of 400 or higher should be considered uncacheable, would lead to the invalid response being inadvertently written to the cache prior to failing the service worker installation. The next time installation was attempted, this previously cached error response wouldn't be retried, so after enough retries, the service worker would eventually finish installation, even though some responses that should have been considered invalid were precached.
If a developer uses a cacheWillUpdate plugin while precaching, returning null from the plugin properly excluded that response from being precached, but it would not cause the overall service worker installation to fail.
Both of these bugs are fixed in the v6.1.0 release. During service worker installation, if any response that is uncacheable (either via the default or custom cacheWillUpdate criteria) is encountered, installation will consistently fail and the invalid response won't be added to the cache.
See #2738
chunks or excludeChunks options could lead to a warning message under some circumstances, due to workbox-webpack-plugin assuming they always corresponded to chunk group names. The code will now check to see if the name matches a chunk itself, not just a group. See #2735source-map dependency has been updated to resolve an issue that could occur when run in a Node environment that had a polyfilled fetch(). See #2716Special thanks to @Spiderpig86 for contributing a PR that was part of this release.
Workbox v6.0.2 resolves an issue that could prevent workbox-precaching from working as expected when loaded via workbox-sw.
Workbox v6.0.2 resolves an issue that could prevent workbox-precaching from working as expected when loaded via workbox-sw.
(There was no v6.0.1 release.)
_handle. [#2687]Special thanks to @pidtuner for raising the issue that was resolved in this release.
This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.
We're happy to announce the release of Workbox v6!
This release includes additional bug fixes for better compatibility with webpack. As of this release, workbox-webpack-plugin requires webpack v4.40.0 or later (for those still on the v4.x branch) or webpack v.5.9.0 or later (for those who have updated to webpack v5.x).
workbox-webpack-plugin will also now take advantage of the immutable metadata that webpack automatically adds to hashed assets. In most cases, this means that explicitly using dontCacheBustURLMatching in your workbox-webpack-plugin configuration is no longer necessary.
See #2651, #2673, and #2675.
The best way to ensure third-party developers have the power to extend Workbox in ways that fully meet their needs is to base our own strategies on top of the extensibility mechanisms we expose to third-party developers.
Specifically, v6 introduces a new way for third-party developers to define their own Workbox strategies, and all of our built-in strategies have been rewritten on top of this mechanism.
This change also allowed us to rewrite the workbox-precaching codebase to use workbox-strategies as a base. This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.
See #2446, #2459 and #2569 for more details.
In v6, all Workbox strategy classes (both built-in strategies as well as custom, third-party strategies) must extend the new Strategy base class.
The Strategy base class is responsible for two primary things:
We previously had internal modules call fetchWrapper and cacheWrapper, which (as their name implies) wrap the various fetch and cache APIs with hooks into their lifecycle. This is the mechanism that currently allows plugins to work, but it's not exposed to developers.
The new "handler" class (which this proposal calls StrategyHandler) will expose these methods so custom strategies can call fetch() or cacheMatch() and have any plugins that were added to the strategy instance automatically invoked.
This class would also make it possible for developers to add their own custom, lifecycle callbacks that might be specific to their strategies, and they would "just work" with the existing plugin interface.
In Workbox v5, plugins are stateless. That means if a request for /index.html triggers both the requestWillFetch and cachedResponseWillBeUsed callbacks, those two callbacks have no way of communicating with each other or even knowing that they were triggered by the same request.
In this proposal, all plugin callbacks will also be passed a new state object. This state object will be unique to this particular plugin object and this particular strategy invocation (i.e. the call to handle()).
This allows developers to write plugins where one callback can conditionally do something based on what another callback in the same plugin did (e.g. compute the time delta between running requestWillFetch and fetchDidSucceed or fetchDidFail).
In order to fully leverage the plugin lifecycle state (mentioned above), you need to know when the lifecycle of a given strategy invocation starts and finishes.
To address this need (and others), the following new plugin lifecycle callbacks will be added:
handle() method returns a response. This callback can be used to modify that response before returning it to a route handler or other custom logic.handle() method returns a response. This callback can be used to record any final response details, e.g. after changes made by other plugins.Developers implementing their own custom strategies do not have to worry about invoking these callbacks themselves; that's all handled by a new Strategy base class.
TypeScript definitions for various callback methods have been normalized. This should lead to a better experience for developers who use TypeScript and write their own code to implement or call handlers.
See #2548.
This release includes a new module, workbox-recipes, that combines common routing and caching strategy configurations into ready-to-use code that can be dropped in to your service worker.
You can read more about what's included in the first batch of recipes, as well as how to use them, in #2664.
A new method, messageSkipWaiting(), has been added to the workbox-window module to simplify the process of telling the "waiting" service worker to activate.
This offers some improvements over alternatives:
It calls postMessage() with the de facto standard message body, {type: 'SKIP_WAITING'}, that a service worker generated by Workbox checks for to trigger skipWaiting().
It chooses the correct "waiting" service worker to post this message to, even if it's not the same service worker that workbox-window was registered with.
See #2394.
Many developers were confused by the concept of "external" events in workbox-window, and in practice, they did not end up being a net-positive.
All "external" events are now represented as "normal" events with an isExternal property set to true. This allows developers who care about the distinction to still detect it, and developers who don't need to know can ignore the property.
See #2031.
Taken together, these two changes make the "Offer a page reload for users" recipe cleaner:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
const showSkipWaitingPrompt = () => {
// This assumes a hypothetical createUIPrompt() method with
// onAccept and onReject callbacks:
const prompt = createUIPrompt({
onAccept: () => {
wb.addEventListener('controlling', () => {
window.location.reload();
});
// This will postMessage() to the waiting service worker.
wb.messageSkipWaiting();
},
onReject: () => {
prompt.dismiss();
}
});
};
// Listening for externalwaiting is no longer needed.
wb.addEventListener('waiting', showSkipWaitingPrompt);
wb.register();
}
</script>
A new boolean parameter, sameOrigin, is passed to the matchCallback function used in workbox-routing. It's set to true if the request is for a same-origin URL, and false otherwise.
This simplifies some common boilerplate:
// In v5:
registerRoute(
({url}) => url.origin === self.location.origin &&
url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'}),
);
// In v6:
registerRoute(
({sameOrigin, url}) => sameOrigin &&
url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'}),
);
See #2487.
You can now set matchOptions in workbox-expiration, which will then be passed through as the CacheQueryOptions to the underlying cache.delete() call. (Most developers won't need to do this.)
See #2206.
workbox-precaching has been updated so that only one entry in the precache manifest is requested and cached at a time, instead of attempting to request and cache all of them at once (leaving it to the browser to figure out how to throttle).
This should reduce the likelihood of net::ERR_INSUFFICIENT_RESOURCES errors while precaching, and also should reduce the bandwidth contention between precaching and simultaneous requests made by the web app.
See #2528.
workbox-precaching now includes a PrecacheFallbackPlugin, which implements the new handlerDidError lifecycle method added in v6.
This makes it easy to specify a precached URL as a "fallback" for a given strategy when a response otherwise wouldn't be available. The plugin will take care of properly constructing the correct cache key for the precached URL, including any revision parameter that's needed.
Here's a sample of using it to respond with a precached /offline.html when the NetworkOnly strategy can't generate a response for a navigation request—in other words, displaying a custom offline HTML page:
import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({request}) => request.mode === 'navigate',
new NetworkOnly({
plugins: [
new PrecacheFallbackPlugin({
fallbackURL: '/offline.html',
}),
],
}),
);
If you're using generateSW to create a service worker for you instead of writing your service worker by hand, you can use the new precacheFallback configuration option in runtimeCaching to accomplish the same thing:
{
// ... other generateSW config options...
runtimeCaching: [{
urlPattern: ({request}) => request.mode === 'navigate',
handler: 'NetworkOnly',
options: {
precacheFallback: {
// This URL needs to be included in your precache manifest.
fallbackURL: '/offline.html',
},
},
}],
}
This release includes a substantial rewrite to the implementation of workbox-precaching, to build on top of other standard Workbox idioms (like Routes, Strategy subclasses, and custom plugins) as much as possible. There are a few breaking changes, described in the follow section, but they are mostly limited to uncommon use cases, when PrecacheController is instantiated directly. For the most part, these changes are meant to be invisible to developers, but should lead to be better consistency in how routing and request handling works across all of Workbox.
You can read more about what's change in #2638
Only GET requests can be used as cache keys, but there are scenarios in which you might want to use a combination of plugins to transform a POST or PUT request into a cacheable GET request.
You can now use the cacheKeyWillBeUsed lifecycle callback in a plugin to return a GET request with whatever URL you'd like to use as a cache key, and that can then allow the response associated with a POST or PUT to be cached.
See #2615 for more details. Thanks to @markbrocato for their contribution.
The minimum required version of node has been increased to v10.0.0. This applies to workbox-build, workbox-cli, and workbox-webpack-plugin. [#2462]
mode was not intended to be a supported parameter for the injectManifest and getManifest modes of workbox-build and workbox-cli. It's been removed from the documentation and attempting to use it outside of generateSW will now trigger a build error. This does not apply to workbox-webpack-plugin, which does support mode in its InjectManifest plugin. [#2464]
skipWaiting() method in workbox-core wrapped the underlying call to self.skipWaiting() in an install handler. In practice, this caused undue confusion and offered little value, as it's valid to call self.skipWaiting() outside of an install event. As of v6, Workbox's skipWaiting() will no longer add in an install handler, and is equivalent to just calling self.skipWaiting(). Because of this, developers should migrate to calling self.skipWaiting() directly, and Workbox's skipWaiting() will likely be removed in v7. [#2547]While this scenario is uncommon, if you precache a URL that corresponds to an HTTP redirect to an HTML document on a different origin, that cross-origin HTML document can no longer be used to satisfy a navigation request. [#2484]
By default, the fbclid URL query parameter is now ignored when looking up a precached response for a given request. [#2532]
Note: The following changes primarily apply to direct usage of the PrecacheController class. Most developers don't use PrecacheController directly, and instead use static helper methods like precacheAndRoute() exported by workbox-precaching. [#2639]
The PrecacheController constructor now takes in an object with specific properties as its parameter, instead of a string. This object supports the following properties: cacheName (serving the same purpose as the string that was passed in to the constructor in v5), plugins (replacing the addPlugins() method from v5), and fallbackToNetwork (replacing the similar option that was passed to createHandler() and `createHandlerBoundToURL() in v5).
The install() and activate() methods of PrecacheController now take exactly one parameter, which should be set to a corresponding InstallEvent or ActivateEvent, respectively.
The addRoute() method has been removed from PrecacheController. In its place, the new PrecacheRoute class can be used to create a route that you can then register.
The precacheAndRoute() method has been removed from PrecacheController. (It still exists as a static helper method exported by the workbox-precaching module.) It was removed because PrecacheRoute can be used instead.
The createMatchCalback() method has been removed from PrecacheController. The new PrecacheRoute can be used instead.
The createHandler() method has been removed from PrecacheController. The strategy property of the PrecacheController object can be used to handle requests instead.
The createHandler() static export has already been removed from the workbox-precaching module. In its place, developers should construct a PrecacheController instance and use its strategy property.
The route registered with precacheAndRoute() is now a "real" route that uses workbox-routing's Router class under the hood. This may lead to a different evaluation order of your routes if you interleave calls to registerRoute() and precacheAndRoute(). See #1857 and #2402 for more details.
setDefaultHandler() method now takes an optional second parameter corresponding to the HTTP method that it applies to, defaulting to 'GET'. It no longer applies to requests with any HTTP method. If you were using setDefaultHandler() and all of your web app's requests are 'GET', then no changes need to be made. [#2463]v4.40.0 (for users remaining on the webpack v4.x major release) or v5.9.0 (for users who have updated to the webpack v5.x major release). [#2641]We're happy to announce the first release candidate of Workbox v6! We do not anticipate any more breaking changes in between now and the official v6 r…
We're happy to announce the first release candidate of Workbox v6! We do not anticipate any more breaking changes in between now and the official v6 release.
In addition to the changes outlined in the previous release notes, the following has changed since Workbox v5.
This release includes a new module, workbox-recipes, that combines common routing and caching strategy configurations into ready-to-use code that can be dropped in to your service worker.
You can read more about what's included in the first batch of recipes, as well as how to use them, in #2664.
This release includes additional bug fixes for better compatibility with webpack. As of this release, workbox-webpack-plugin requires webpack v4.40.0 or later (for those still on the v4.x branch) or webpack v.5.4.0 or later (for those who have updated to webpack v5.x).
workbox-webpack-plugin will also now take advantage of the immutable metadata that webpack automatically adds to hashed assets. In most cases, this means that explicitly using dontCacheBustURLMatching in your workbox-webpack-plugin configuration is no longer necessary.
See #2651, #2673, and #2675.
Thank you to @dermoumi for their contributions to this release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
…plugins) as much as possible. There are a few breaking changes, described in the follow section, but they are mostly limited to uncommon use cases, wh…
We're happy to announce the third alpha release of Workbox v6! In addition to the changes outlined in the previous release notes, the following has changed since Workbox v5.
This release includes a substantial rewrite to the implementation of workbox-precaching, to build on top of other standard Workbox idioms (like Routes, Strategy subclasses, and custom plugins) as much as possible. There are a few breaking changes, described in the follow section, but they are mostly limited to uncommon use cases, when PrecacheController is instantiated directly. For the most part, these changes are meant to be invisible to developers, but should lead to be better consistency in how routing and request handling works across all of Workbox.
You can read more about what's change in #2638
As of this release, workbox-webpack-plugin should be compatible with webpack v5.0.0. We have also raised the minimum required version of webpack to v4.4.0, which should be a straightforward upgrade for developers who need to remain on webpack v4.x.
While all of the public interfaces remain the same, signfifcant changes were made to the code used to determine which webpack assets make it into your precache manifest. These take advantage of new methods that were added in webpack v4.4.0, and which have to be used in webpack v5.0.0. We encourage developers to test workbox-webpack-plugin carefully, and raise issues if you find discrepencies like URLs missing from your precache manifest! This applies whether you are remaining on webpack v4.4.0, or are upgrade to webpack v5.0.0.
Note: At this time, workbox-webpack-plugin has issues detecting the correct URLs for HTML assets created by html-webpack-plugin in webpack v5.0.0. You can follow https://github.com/jantimon/html-webpack-plugin/issues/1522 for updates.
Only GET requests can be used as cache keys, but there are scenarios in which you might want to use a combination of plugins to transform a POST or PUT request into a cacheable GET request.
You can now use the cacheKeyWillBeUsed lifecycle callback in a plugin to return a GET request with whatever URL you'd like to use as a cache key, and that can then allow the response associated with a POST or PUT to be cached.
See #2615 for more details. Thanks to @markbrocato for their contribution.
Note: The following changes primarily apply to direct usage of the PrecacheController class. Most developers don't use PrecacheController directly, and instead use static helper methods like precacheAndRoute() exported by workbox-precaching. [#2639]
The PrecacheController constructor now takes in an object with specific properties as its parameter, instead of a string. This object supports the following properties: cacheName (serving the same purpose as the string that was passed in to the constructor in v5), plugins (replacing the addPlugins() method from v5), and fallbackToNetwork (replacing the similar option that was passed to createHandler() and `createHandlerBoundToURL() in v5).
The install() and activate() methods of PrecacheController now take exactly one parameter, which should be set to a corresponding InstallEvent or ActivateEvent, respectively.
The addRoute() method has been removed from PrecacheController. In its place, the new PrecacheRoute class can be used to create a route that you can then register.
The precacheAndRoute() method has been removed from PrecacheController. (It still exists as a static helper method exported by the workbox-precaching module.) It was removed because PrecacheRoute can be used instead.
The createMatchCalback() method has been removed from PrecacheController. The new PrecacheRoute can be used instead.
The createHandler() method has been removed from PrecacheController. The strategy property of the PrecacheController object can be used to handle requests instead.
The createHandler() static export has already been removed from the workbox-precaching module. In its place, developers should construct a PrecacheController instance and use its strategy property.
The route registered with precacheAndRoute() is now a "real" route that uses workbox-routing's Router class under the hood. This may lead to a different evaluation order of your routes if you interleave calls to registerRoute() and precacheAndRoute(). See #1857 and #2402 for more details.
v4.4.0. (See previous section for other webpack updates.) [#2641]We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
Workbox v6.0.0-alpha.2 includes updates to various underlying npm dependencies, but is otherwise identical to the previous `v6.0.0-alpha.1` release.
Workbox v6.0.0-alpha.2 includes updates to various underlying npm dependencies, but is otherwise identical to the previous v6.0.0-alpha.1 release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.
We're happy to announce the first alpha release of Workbox v6!
The best way to ensure third-party developers have the power to extend Workbox in ways that fully meet their needs is to base our own strategies on top of the extensibility mechanisms we expose to third-party developers.
Specifically, v6 introduces a new way for third-party developers to define their own Workbox strategies, and all of our built-in strategies have been rewritten on top of this mechanism.
This change also allowed us to rewrite the workbox-precaching codebase to use workbox-strategies as a base. This should not result in any breaking changes, and should lead to better long-term consistency in how the two modules access the network and cache.
See #2446, #2459 and #2569 for more details.
In v6, all Workbox strategy classes (both built-in strategies as well as custom, third-party strategies) must extend the new Strategy base class.
The Strategy base class is responsible for two primary things:
We previously had internal modules call fetchWrapper and cacheWrapper, which (as their name implies) wrap the various fetch and cache APIs with hooks into their lifecycle. This is the mechanism that currently allows plugins to work, but it's not exposed to developers.
The new "handler" class (which this proposal calls StrategyHandler) will expose these methods so custom strategies can call fetch() or cacheMatch() and have any plugins that were added to the strategy instance automatically invoked.
This class would also make it possible for developers to add their own custom, lifecycle callbacks that might be specific to their strategies, and they would "just work" with the existing plugin interface.
In Workbox v5, plugins are stateless. That means if a request for /index.html triggers both the requestWillFetch and cachedResponseWillBeUsed callbacks, those two callbacks have no way of communicating with each other or even knowing that they were triggered by the same request.
In this proposal, all plugin callbacks will also be passed a new state object. This state object will be unique to this particular plugin object and this particular strategy invocation (i.e. the call to handle()).
This allows developers to write plugins where one callback can conditionally do something based on what another callback in the same plugin did (e.g. compute the time delta between running requestWillFetch and fetchDidSucceed or fetchDidFail).
In order to fully leverage the plugin lifecycle state (mentioned above), you need to know when the lifecycle of a given strategy invocation starts and finishes.
To address this need (and others), the following new plugin lifecycle callbacks will be added:
handle() method returns a response. This callback can be used to modify that response before returning it to a route handler or other custom logic.handle() method returns a response. This callback can be used to record any final response details, e.g. after changes made by other plugins.Developers implementing their own custom strategies do not have to worry about invoking these callbacks themselves; that's all handled by a new Strategy base class.
TypeScript definitions for various callback methods have been normalized. This should lead to a better experience for developers who use TypeScript and write their own code to implement or call handlers.
See #2548.
A new method, messageSkipWaiting(), has been added to the workbox-window module to simplify the process of telling the "waiting" service worker to activate.
This offers some improvements over alternatives:
It calls postMessage() with the de facto standard message body, {type: 'SKIP_WAITING'}, that a service worker generated by Workbox checks for to trigger skipWaiting().
It chooses the correct "waiting" service worker to post this message to, even if it's not the same service worker that workbox-window was registered with.
See #2394.
Many developers were confused by the concept of "external" events in workbox-window, and in practice, they did not end up being a net-positive.
All "external" events are now represented as "normal" events with an isExternal property set to true. This allows developers who care about the distinction to still detect it, and developers who don't need to know can ignore the property.
See #2031.
Taken together, these two changes make the "Offer a page reload for users" recipe cleaner:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
const showSkipWaitingPrompt = () => {
// This assumes a hypothetical createUIPrompt() method with
// onAccept and onReject callbacks:
const prompt = createUIPrompt({
onAccept: () => {
wb.addEventListener('controlling', () => {
window.location.reload();
});
// This will postMessage() to the waiting service worker.
wb.messageSkipWaiting();
},
onReject: () => {
prompt.dismiss();
}
});
};
// Listening for externalwaiting is no longer needed.
wb.addEventListener('waiting', showSkipWaitingPrompt);
wb.register();
}
</script>
A new boolean parameter, sameOrigin, is passed to the matchCallback function used in workbox-routing. It's set to true if the request is for a same-origin URL, and false otherwise.
This simplifies some common boilerplate:
// In v5:
registerRoute(
({url}) => url.origin === self.location.origin &&
url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'}),
);
// In v6:
registerRoute(
({sameOrigin, url}) => sameOrigin &&
url.pathname.endsWith('.png'),
new StaleWhileRevalidate({cacheName: 'local-png'}),
);
See #2487.
You can now set matchOptions in workbox-expiration, which will then be passed through as the CacheQueryOptions to the underlying cache.delete() call. (Most developers won't need to do this.)
See #2206.
workbox-precaching has been updated so that only one entry in the precache manifest is requested and cached at a time, instead of attempting to request and cache all of them at once (leaving it to the browser to figure out how to throttle).
This should reduce the likelihood of net::ERR_INSUFFICIENT_RESOURCES errors while precaching, and also should reduce the bandwidth contention between precaching and simultaneous requests made by the web app.
See #2528.
workbox-precaching now includes a PrecacheFallbackPlugin, which implements the new handlerDidError lifecycle method added in v6.
This makes it easy to specify a precached URL as a "fallback" for a given strategy when a response otherwise wouldn't be available. The plugin will take care of properly constructing the correct cache key for the precached URL, including any revision parameter that's needed.
Here's a sample of using it to respond with a precached /offline.html when the NetworkOnly strategy can't generate a response for a navigation request—in other words, displaying a custom offline HTML page:
import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
({request}) => request.mode === 'navigate',
new NetworkOnly({
plugins: [
new PrecacheFallbackPlugin({
fallbackURL: '/offline.html',
}),
],
}),
);
If you're using generateSW to create a service worker for you instead of writing your service worker by hand, you can use the new precacheFallback configuration option in runtimeCaching to accomplish the same thing:
{
// ... other generateSW config options...
runtimeCaching: [{
urlPattern: ({request}) => request.mode === 'navigate',
handler: 'NetworkOnly',
options: {
precacheFallback: {
// This URL needs to be included in your precache manifest.
fallbackURL: '/offline.html',
},
},
}],
}
The minimum required version of node has been increased to v10.0.0. This applies to workbox-build, workbox-cli, and workbox-webpack-plugin. [#2462]
mode was not intended to be a supported parameter for the injectManifest and getManifest modes of workbox-build and workbox-cli. It's been removed from the documentation and attempting to use it outside of generateSW will now trigger a build error. This does not apply to workbox-webpack-plugin, which does support mode in its InjectManifest plugin. [#2464]
skipWaiting() method in workbox-core wrapped the underlying call to self.skipWaiting() in an install handler. In practice, this caused undue confusion and offered little value, as it's valid to call self.skipWaiting() outside of an install event. As of v6, Workbox's skipWaiting() will no longer add in an install handler, and is equivalent to just calling self.skipWaiting(). Because of this, developers should migrate to calling self.skipWaiting() directly, and Workbox's skipWaiting() will likely be removed in v7. [#2547]While this scenario is uncommon, if you precache a URL that corresponds to an HTTP redirect to an HTML document on a different origin, that cross-origin HTML document can no longer be used to satisfy a navigation request. [#2484]
By default, the fbclid URL query parameter is now ignored when looking up a precached response for a given request. [#2532]
setDefaultHandler() method now takes an optional second parameter corresponding to the HTTP method that it applies to, defaulting to 'GET'. It no longer applies to requests with any HTTP method. If you were using setDefaultHandler() and all of your web app's requests are 'GET', then no changes need to be made. [#2463]We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
Nothing published for this version
The v5.1.4 release contains a dependency update for rollup-plugin-terser, resolving a security error with one of its dependencies.
The v5.1.4 release contains a dependency update for rollup-plugin-terser, resolving a security error with one of its dependencies.
See https://github.com/GoogleChrome/workbox/issues/2601
Correct workbox-build's getManifest() JSDoc [#2429]
workbox-buildworkbox-build's getManifest() JSDoc [#2429]workbox-cliswSrc for hardcoded injection point in wizard flow [#2451]workbox-corehandlerCallback JSDocs update [#2440]workbox-precachingisSWEnv assertion [#2453]is [#2466]Special thanks to @akonchady for contributing a PR that went in to this release.
Reverted the strip-comments dependency to an earlier revision, to provide continued compatibility with the v8.x.y releases of node. [#2416]
workbox-buildstrip-comments dependency to an earlier revision, to provide continued compatibility with the v8.x.y releases of node. [#2416]Special thanks to @Mister-Hope for raising issues that were resolved in this release.
_(We ran into some issues with the v5.1.0 release process, so v5.1.1 is a republish of the same code.)_
(We ran into some issues with the v5.1.0 release process, so v5.1.1 is a republish of the same code.)
workbox-routinghash portion is displayed. [#2371]workbox-webpack-plugincompileSrc option (defaulting to true) has been added. If set to false, then webpack will not run the swSrc file through a compilation. This can be useful if you want your swDest output to be, e.g., a JSON file which contains your precache manifest. [#2412]workbox-webpack-pluginwebpack modules. [#2397]webpackCompilationPlugins that customize the swSrc compilation should now be properly applied. [#2400]Special thanks to @aritsune, @bailnl, @novaknole and @pizzafox for raising issues that were resolved in this release.
Nothing published for this version
We're happy to announce the release of Workbox version 5! This release introduces a lot of new features, as well as some breaking changes.
We're happy to announce the release of Workbox version 5! This release introduces a lot of new features, as well as some breaking changes.
If you're already using Workbox, the best place to get up to speed is the guide to migrating from v4 to v5.
One example migration, with commentary, can be found in this GitHub commit.
While our immediate plan is to continue publishing copies of the Workbox runtime code to our CDN, in v5, the generateSW mode of our build tools will create a local bundle of exactly the Workbox runtime methods you end up using in your service worker. Depending on the value of inlineWorkboxRuntime, this bundle will either be imported from a separate file, or inlined directly in your top-level service worker.
Under the hood, we use Rollup to create this optimized bundle, optionally minifying it and generating sourcemaps, depending on the configuration.
See #2064 for more details.
If you're using the workbox-webpack-plugin's InjectManifest mode, the service worker file you specify via swSrc will end up being run through a webpack compilation process, optionally applying any compilation plugins configured via the webpackPlugins parameter. This should simplify the development flow described in the Using Bundlers (webpack/Rollup) with Workbox guide.
See #1513 for more details.
You can continue using importScripts('http://storage.googleapis.com/workbox-cdn/releases/5.0.0/workbox-sw.js') and relying on <code>workbox-sw</code> to dynamically pull in the Workbox runtime code that you need in v5, but we expect that using a custom bundle will lead to smaller runtime payloads (as well as work around issues with asynchronous imports), and we encourage developers to consider switching off of the CDN.
Before v5, workbox-webpack-plugin would generate a list of entries to precache based on two distinct sources: the set of assets in a webpack compilation, along with an optional additional set of files matched via glob patterns. Most webpack developers did not use the glob-related options (since the webpack compilation would normally include all the assets that they cared about), but at the same time, some helpful configuration options for manipulating or post-processing the precache manifest only applied to entries created via those glob patterns.
In v5, the glob-related configuration options are no longer supported. The webpack asset pipeline is the source of all the automatically created manifest entries. (Developers who have files that exist outside of the webpack asset pipeline are encouraged to use, e.g., <code>copy-webpack-plugin</code> to get those files into the <code>webpack</code> compilation.)
Beyond that, options for post-processing the precache manifest can now be used to manipulate entries that originate from the webpack asset pipeline. manifestTransforms, in particular, can be used to make arbitrary changes to any aspect of the precache manifest, including adding entries, deleting them, and changing their revision or url fields as needed. The current webpack compilation will be passed in to the callback function in case you need information from there to determine how to manipulate entries.
Here's an example of using manifestTransforms to perform extensive post-processing of a precache manifest:
const manifestTransform = (originalManifest, compilation) => {
// If anything needs to be propagated to webpack's list
// of compilaiton warnings, add the message here:
const warnings = [];
const manifest = originalManifest.map((entry) => {
// entry has size, revision, and url fields.
// Add a CDN prefix to certain URLs.
// (alternatively, use modifyURLPrefix)
if (entry.url.endsWith('.jpg')) {
entry.url = `https://examplecdn.com/${entry.url}`;
}
// Remove revision when there's a match for your hashed URL pattern.
// (alternatively, just set dontCacheBustURLsMatching)
if (entry.url.match(/\.[0-9a-f]{6}\./)) {
delete entry.revision;
}
// Exclude assets greater than 1MB, unless they're JPEGs.
// (alternatively, use maximumFileSizeToCacheInBytes)
if ((entry.size > 1024 * 1024) && !entry.url.endsWith('.jpg')) {
warnings.push(`${entry.url} will not be precached because it is too big.`);
return null;
}
return entry;
}).filter(Boolean); // Exclude any null entries.
// When manually adding in additional entries, make sure you use a URL
// that already includes versioning info, like the v1.0.0 below:
manifest.push({
url: 'https://examplecdn.com/third-party-code/v1.0.0/index.js',
});
return {manifest, warnings};
};
Helpers that implement common manifest transformations, like maximumFileSizeToCacheInBytes, dontCacheBustURLsMatching and modifyURLPrefix, are also supported for webpack assets.
Additionally, in v5, the precache manifest is inlined into the top-level service worker file, and not stored in a separate, external JavaScript file.
Prior to v5, manifest injection worked by using a regular expression to find the correct location in the source service worker file to replace with the array of manifest entries. This could be brittle, and it was hard to customize, since the replacement step assumed you were using a RegExp that had capture groups.
This is simplified in v5, and using the injectManifest mode just checks for a placeholder variable and performs the equivalent of string replacement to inject the full manifest in its place. This variable is self.__WB_MANIFEST by default.
Your swSrc file in v4 might have looked like precacheAndRoute([]);
In v5, you should change this to precacheAndRoute(self.__WB_MANIFEST);
self.__WB_MANIFEST was chosen as the default replacement because self should always be defined in the service worker global scope, and it is unlikely to conflict with any user-created variables. If you need a different replacement, it can be configured via the injectionPoint option.
See #2059 for more details.
All browser-based Workbox packages are now written in TypeScript and type definitions have been published to npm. TypeScript users (as well as users with TypeScript-aware code editors) can now get type checking for all browser-exposed Workbox APIs. (There are no TypeScript definitions for the various Workbox build tools at this time.)
To get type definitions for any Workbox APIs, you can import the package as described in our guide on Using Bundlers (webpack/Rollup) with Workbox. For example:
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {Plugin as ExpirationPlugin} from 'workbox-expiration';
registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
new CacheFirst({
cacheName: 'images',
plugins: [
new ExpirationPlugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
}),
);
Note, we've historically published our Workbox source modules with the .mjs extension as a way to disambiguate them from classic scripts and the examples in our documentation that reference file paths always use .mjs.
However, since TypeScript does not currently support importing .mjs files we publish both .js and .mjs files to npm. TypeScript users wanting to import an individual module should be able to reference it by omitting the extension (which will then default to the .js file).
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {Plugin as ExpirationPlugin} from 'workbox-expiration';
If you encounter any problems with the type definitions or importing the source files via TypeScript, please let us know by opening an issue on GitHub.
All of the build tools (generateSW and injectManifest modes in workbox-build, workbox-cli, and workbox-webpack-plugin) now support a new option: additionalManifestEntries. [#2124] It can be set to a list of additional precache manifest entries that go beyond what would normally be included as part of your build (such as CDN URLs), and is a shortcut to something that is otherwise possible via the manifestTransforms option.
Before using this feature, please keep in mind that workbox-precaching requires one of two things from each entry in order to keep precached content up to date:
revision field alongside an unversioned URL, providing versioning information that is updated each time new contents are deployed to that URL. E.g. {url: https://example.com/index.js, revision: hashOfIndexJsContents}The precache manifest entries generated by Workbox's built tools can automatically add in revision fields for you, but when using additionalManifestEntries, it's up to you to ensure that you only add in versioned URLs, or that you include a revision field that will always change whenever the corresponding URL changes.
To ensure that developers are aware of this, passing in string values in the additionalManifestEntries will result in a non-fatal warning message, asking you to confirm that your URLs are versioned. To avoid this message, pass in an object with a revision: null property instead of a string, like {url: http://example.com/v1.0.0/index.js, revision: null}.
A new option, importScriptsViaChunks, is supported in the GenerateSW mode of the webpack plugin. [#2131] Passing in one or more chunk names will cause the corresponding script files to be included in the generated service worker, via <code>importScripts()</code>.
Because of the way script caching works with importScripts(), developers should ensure that their chunks' filenames include a hash, so that changes to a chunk's contents will result in new filename.
Precache manifest entries can now include an optional property, integrity. If provided, that value will be treated as the integrity metadata for in the fetch() request used to populate the precache. [#2141]
There is currently no option in the Workbox build tools for generating this metadata; it's left as an exercise to developers to use the manifestTransforms option to post-process the generated precache manifests and add in integrity properties, with appropriate values, to the entries that need that extra validation.
A new update() method has been added to workbox-window. When called, it will invoke the update() method on the underlying ServiceWorkerRegistration object. [#2136]
Calling this method is optional, as browsers will automatically check for service worker updates whenever there's a navigation request to a new page, along with a few other scenarios. However, as described in this guide, manually requesting a service worker update can be useful for long-lived, single-page apps.
Two options that were previously supported for navigation routes, blacklist and whitelist have been renamed denylist and allowlist.
workbox-routing previously supported a method, registerNavigationRoute(), that, under the hood, did two things:
fetch event had a <code>mode of 'navigate'</code>.This is a common pattern to use when implementing the App Shell architecture.
The second step, generating a response by reading from the cache, falls outside of what we see as the responsibilities of workbox-routing. Instead, we see it as functionality that should be part of workbox-precaching, via a new method, createHandlerBoundToURL(). This new method can work hand-in-hand with the existing NavigationRoute class in workbox-routing to accomplish the same logic.
If you're using the navigateFallback option in one of the build tool's "generate SW" mode, then the switchover will happen automatically. If you previously configured either the navigateFallbackBlacklist or navigateFallbackWhitelist options, please change those to navigateFallbackDenylist or navigateFallbackAllowlist, respectively.
If you're using "inject manifest" mode or just writing the service worker yourself, and your Workbox v4 service worker calls registerNavigationRoute() directly, then you'll have to make a change to your code to get the equivalent behavior.
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
You no longer need to call getCacheKeyForURL(), as createHandlerBoundToURL() will take care of that for you.
A generatePayload() configuration option has been added to the BroadcastCacheUpdate and BroadcastUpdatePlugin classes that allows developers to customize the message that gets sent to the window when a cached response has been updated.
The generatePayload() function is called with the same arguments as the <code>cacheDidUpdate()</code> plugin callback, and its return value will be used as the message payload. Here's an example that adds the <code>Last-Modified</code> header value of the updated response to the payload:
new BroadcastUpdatePlugin({
generatePayload({request, newResponse}) {
return {
url: request.url,
lastModified: newResponse.headers.get('Last-Modified'),
};
},
});
A copyResponse() method has been added that can be used to clone a response and modify its headers, status, or statusText. [#2193]
Here's an example that adds a custom header to indicate that a response came from the cache (and not the network):
const newResponse = copyResponse(oldResponse, (responseInit) => {
responseInit.headers.set('X-Cache', 'hit');
return responseInit;
});
If workbox-precaching needs to bypass the HTTP cache when requesting a URL, it will now set cache: 'reload' on the outgoing Request, which in turns sets the appropriate Cache-Control headers. [#2176]
Previously, bypassing the HTTP cache was done by adding in a __WB_REVISION=... URL query parameter to the outgoing network request, meaning that backend web servers would see requests for URLs containing those query parameters. With this change in place, requests for URLs with __WB_REVISION=... should no longer be seen in HTTP server logs.
Please note that this change only applies to outgoing HTTP requests used to populate the precache, and does not apply to cache keys. The keys for some entries created by workbox-precaching still include the __WB_REVISION=... parameter, and it's still a best practice to call getCacheKeyForURL() to determine the actual cache key, including the __WB_REVISION parameter, if you need to access precached entries using the Cache Storage API directly.
A new __WB_DISABLE_DEV_LOGS global has been added. Set it to false to disable all logging in development mode. [#2284]
Two new methods (matchPrecache() and createHandler()) have been added to make it easier to manually access precached assets. [#2254]
Any manifestTransform callbacks are now treated as being <code>async</code>, and each callback will be <code>await</code>-ed by the build tools. If you supply multiple transforms, they will still be run sequentially, in the same order. [#2195]
This should not be a breaking change, as you can continue providing non-async callback functions, and they will still work as before.
As part of a general refactoring of how the options passed to all of our build tools are parsed [#2191], using precaching in the generateSW mode of workbox-build and workbox-cli is no longer mandatory. You can now use the runtimeCaching options without configuring the glob-related options, and your generated service worker will just contain the corresponding runtime caching routes.
If you don't configure the glob-related options and you don't use runtimeCaching, that will lead to a build error.
A number of workbox-build, workbox-cli, and workbox-webpack-plugin configuration parameters are no longer supported, following the general outlines of the changes described above. For instance, generateSW will always create a local Workbox runtime bundle for you, so the importWorkboxFrom option no longer makes sense. Please consult the relevant tool's documentation for the list of supported options.
navigationRouteWhitelist has been renamed navigationRouteAllowlist, and navigationRouteBlacklist has been renamed navigationRouteDenylist. The functionality is otherwise identical.
All Plugin classes have been renamed to be package-specific, e.g. ExpirationPlugin, CacheableResponsePlugin, etc. If you're using one of the Workbox build tools in generateSW mode to create your service worker, this change will be handled for you automatically. If you use one of the plugins in a manually created service worker, you'll need to explicitly change instances of Plugin to the correct revised class name. [#2187]
The workbox-broadcast-update package no longer uses BroadcastChannel, even in cases when the browser supports it. Instead it uses postMessage() to message window clients. [#2184]
This change was made because postMessage() messages are automatically buffered by the window to handle cases where the service worker sends a message before the code running on the window is ready to receive it. BroadcastChannel has no such buffering, and thus you're more likely to miss message when using it.
If you're currently listening for BroadcastChannel messages in your code running on the window, you'll now need to listen for message events on the <code>ServiceWorkerContainer</code>:
navigator.serviceWorker.addEventListener('message', (event) => {
console.log(event.data);
})
Note: workbox-window users should not need to make any changes, as its internal logic has been updated to listen for postMessage() calls.
The generateSWString mode has been removed. We expect the impact of this to be minimal, as it was primarily used internally by workbox-webpack-plugin.
The minimum required version of node has been increased to v8.0.0. This also applies to build tools that use workbox-build, like workbox-cli and workbox-webpack-plugin.
makeRequest() in favor of handle(). Calling makeRequest() is mostly equivalent to calling handle() on one of the workbox-strategy classes. The differences between the two methods were so slight that keeping both around did not make sense. Developers who called makeRequest() should be able to switch to using handle() without any further change. [#2123]webpack v4 or higher.swSrc file has an associated sourcemap, we now update that to account for the injected manifest. [#2239]cacheWillUpdate() plugin callback was not being await-ed. [#2287]matchCallback string/number return values through to handlerCallback. [#2134]ReadableStream bug in development mode in Safari. [#2268]workbox-webpack-plugin in the same compilation, assets created by those other instances will now be excluded from each others' precache manifest. [#2182]isUpdate property to the controlling event, which was documented but not actually implemented. [#2114]message event listener is now added earlier, inside of the constructor rather than the register() method. [#2211]A sincere thank you to everyone who tested Workbox v5, and in particular to the following folks who filed bugs and made contributions to the code. (Apologies if we've missed anyone—it's been a long process!)
…property, matching the behavior of the (now deprecated) makeRequest() method. [#2317]
The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
Improvements to the JSDoc documentation for all of the build tools. [#2320]
whitelist/blacklist (in the NavigationRoute class) and navigateFallbackWhitelist/navigateFallbackBlacklist (in the build tools) have been renamed to allowlist/denylist and navigateFallbackAllowlist/navigateFallbackDenylist. Functionality remains the same. [#2325]
injectManifest mode. [#2301]revision: null instead of deleting the revision property when the build tool determines that the revision isn't necessary. [#2326]__WB_DISABLE_DEV_LOGS value that's explicitly set by your service worker script. [#2296]handle() method of each strategy now supports passing in a string URL as the request property, matching the behavior of the (now deprecated) makeRequest() method. [#2317]Calling precache()/precacheAndRoute() and passing in an precache manifest entry that is just a string has been deprecated. It will trigger a warning m…
The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
__WB_DISABLE_DEV_LOGS global has been added to disable all logging in development mode. [#2284]precache()/precacheAndRoute() and passing in an precache manifest entry that is just a string has been deprecated. It will trigger a warning message in v5, and will be treated as a runtime error in a future release. If you need to use a hardcoded URL as a manifest entry, first ensure that it contains inline revision information, like a hash. Then, instead of passing in a string like '/app.1234abcd.js', use {url: '/app.1234abcd.js', revision: null} to explicitly state that the revision is meant to be null. [#2262]ReadableStream bug in development mode in Safari. [#2268]cacheWillUpdate() plugin callback was not being await-ed. [#2287]The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-rele
The latest release candidate of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
workbox-core [#2255]"strict": true in their TypeScript config. [#2241, #2244, #2256 2246]matchPrecache() and createHandler()) have been added to make it easier to manually access precached assets. [#2254]Missing source map assets are is no longer treated as a fatal error. [#2251]
If the swSrc file has an associated sourcemap, we now update that to account for the injected manifest. [#2239]
createHandlerForURL() method has been renamed to createHandlerBoundToURL() to make its intended usage more clear. [#2254]The latest beta release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
The latest beta release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
swSrc file has an associated sourcemap, we now update that to account for the injected manifest. [#2239]Fixed a bug that could lead to the output directory being prepended twice when writing the service worker to disk. [#2223]
Make sure that all swSrc and swDest files are left out of the generated precache manifest. [#2232]
__WB_REVISION__ query parameter to outgoing network requests that should be cache-busted, explicitly set the cache mode to 'reload' if needed. When cache-busting is not needed, set cache to 'default'. [#2222]206 Partial Content response to be used when the incoming request used Range: bytes=0-. [#2237]message event listener is now added earlier, inside of the constructor rather than the register() method. [#2211]Special thanks to @lukas2005 for their bug reports, and @azizhk for their contributions that went into this release!
This should not be a breaking change, as you can continue providing non-async callback functions, and they will still work as before.
The latest beta release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
A generatePayload() configuration option has been added to the BroadcastCacheUpdate and BroadcastUpdatePlugin classes that allows developers to customize the message that gets sent to the window when a cached response has been udpated.
The generatePayload() function is called with the same arguments as the cacheDidUpdate() plugin callback, and its return value will be used as the message payload. Here's an example that adds the Last-Modified header value of the updated response to the payload:
new BroadcastUpdatePlugin({
generatePayload({request, newResponse}) {
return {
url: request.url,
lastModified: newResponse.headers.get('Last-Modified'),
};
},
});
A copyResponse() method has been added that can be used to clone a response and modify its headers, status, or statusText. [#2193]
Here's an example that adds a custom header to indicate that a response came from the cache (and not the network):
const newResponse = copyResponse(oldResponse, (responseInit) => {
responseInit.headers.set('X-Cache', 'hit');
return responseInit;
});
If workbox-precaching needs to bypass the HTTP cache when requesting a URL, it will now set cache: 'reload' on the outgoing Request, which in turns sets the appropriate Cache-Control headers. [#2176]
Previously, bypassing the HTTP cache was done by adding in a __WB_REVISION=... URL query parameter to the outgoing network request, meaning that backend web servers would see requests for URLs containing those query parameters. With this change in place, requests for URLs with __WB_REVISION=... should no longer be seen in HTTP server logs.
Please note that this change only applies to outgoing HTTP requests used to populate the precache, and does not apply to cache keys. The keys for some entries created by workbox-precaching still include the __WB_REVISION=... parameter, and it's still a best practice to call getCacheKeyForURL() to determine the actual cache key, including the __WB_REVISION parameter, if you need to access precached entries using the Cache Storage API directly.
Any manifestTransform callbacks are now treated as being async, and each callback will be await-ed by the build tools. If you supply multiple transforms, they will still be run sequentially, in the same order. [#2195]
This should not be a breaking change, as you can continue providing non-async callback functions, and they will still work as before.
As part of a general refactoring of how the options passed to all of our build tools are parsed [#2191], using precaching in the generateSW mode of workbox-build and workbox-cli is no longer mandatory. You can now use the runtimeCaching options without configuring the glob-related options, and your generated service worker will just contain the corresponding runtime caching routes.
If you don't configure the glob-related options and you don't use runtimeCaching, that will lead to a build error.
The workbox-broadcast-update package no longer uses BroadcastChannel, even in cases when the browser supports it. Instead it uses postMessage() to message window clients. [#2184]
This change was made because postMessage() messages are automatically buffered by the window to handle cases where the service worker sends a message before the code running on the window is ready to receive it. BroadcastChannel has no such buffering, and thus you're more likely to miss message when using it.
If you're currently listening for BroadcastChannel messages in your code running on the window, you'll now need to listen for message events on the ServiceWorkerContainer:
navigator.serviceWorker.addEventListener('message', (event) => {
console.log(event.data);
})
Note: workbox-window users should not need to make any changes, as its internal logic has been updated to listen for postMessage() calls.
Plugin classes have been renamed to be package-specific, e.g. ExpirationPlugin, CacheableResponsePlugin, etc. If you're using one of the Workbox build tools in generateSW mode to create your service worker, this change will be handled for you automatically. If you use one of the plugins in a manually created service worker, you'll need to explicitly change instances of Plugin to the correct revised class name. [#2187]RouteHandlerObject type has been added to fix TypeScript typing issue when using strategy classes as route handlers. [#2183]importScriptsViaChunks will only call importScripts() on assets in that chunk which have a .js extension. [#2164]GenerateSW mode will now work properly when there are multiple compilations (via, e.g., webpack-dev-server). [#2167]json-stable-stringify dependency has been replaced by fast-json-stable-stringify. [#2163]workbox-webpack-plugin in the same compilation, assets created by those other instances will now be excluded from each others' precache manifest. [#2182]Special thanks to @kaykayehnn for their bug reports and contributions that went into this release.
All of the build tools (generateSW and injectManifest modes in workbox-build, workbox-cli, and workbox-webpack-plugin) now support a new option: addit
All of the build tools (generateSW and injectManifest modes in workbox-build, workbox-cli, and workbox-webpack-plugin) now support a new option: additionalManifestEntries. [#2124] It can be set to a list of additional precache manifest entries that go beyond what would normally be included as part of your build (such as CDN URLs), and is a shortcut to something that is otherwise possible via the manifestTransforms option.
Before using this feature, please keep in mind that workbox-precaching requires one of two things from each entry in order to keep precached content up to date:
The URL contains versioning information, and therefore the contents will never change. E.g. 'https://example.com/<b>v1.0.0</b>/index.js', or 'https://example.com/index.<b>hashValue</b>.js'
You include a revision field alongside an unversioned URL, providing versioning information that is updated each time new contents are deployed to that URL. E.g. {url: https://example.com/index.js, revision: hashOfIndexJsContents}
The precache manifest entries generated by Workbox's built tools can automatically add in revision fields for you, but when using additionalManifestEntries, it's up to you to ensure that you only add in versioned URLs, or that you include a revision field that will always change whenever the corresponding URL changes.
To ensure that developers are aware of this, passing in string values in the additionalManifestEntries will result in a non-fatal warning message, asking you tot confirm that your URLs are versioned. To avoid this message, pass in an object with a revision: null property instead of a string, like {url: http://example.com/v1.0.0/index.js, revision: null}.
A new option, importScriptsViaChunks, is supported in the GenerateSW mode of the webpack plugin. [#2131] Passing in one or more chunk names will cause the corresponding script files to be included in the generated service worker, via importScripts().
Because of the way script caching works with importScripts(), developers should ensure that their chunks' filenames include a hash, so that changes to a chunk's contents will result in new filename.
Precache manifest entries can now include an optional property, integrity. If provided, that value will be treated as the integrity metadata for in the fetch() request used to populate the precache. [#2141]
There is currently no option in the Workbox build tools for generating this metadata; it's left as an exercise to developers to uses the manifestTransforms option to post-process the generated precache manifests and add in integrity properties, with appropriate values, to the entries that need that extra validation.
A new update() method has been added to workbox-window. When called, it will invoke the update() method on the underlying ServiceWorkerRegistration object. [#2136]
Calling this method is optional, as browsers will automatically check for service worker updates whenever there's a navigation request to a new page, along with a few other scenarios. However, as described in this guide, manually requesting a service worker update can be useful for loong-lived, single-page apps.
Calling makeRequest() is mostly equivalent to calling handle() on one of the workbox-strategy classes. The differences between the two methods were so slight that keeping both around did not make sense. Developers who called makeRequest() should be able to switch to using handle() without any further change. [#2123]
workbox-routing previously supported a method, registerNavigationRoute(), that, under the hood, did two things:
fetch event had a mode of 'navigate'.(This is a common pattern to use when implementing the App Shell architecture.)
The second step, generating a response by reading from the cache, falls outside of what we envision workbox-routing accomplishing. Instead, we see it as functionality that should be part of workbox-precaching, via a new method, createHandlerForURL(). This new method can work hand-in-hand with the existing NavigationRoute class in workbox-routing to accomplish the same logic. [#2143]
If you're using the navigateFallback option in one of the build tool's generateSW mode, then the switchover will happen automatically, without requiring any change on your part.
If you're using injectManifest mode and your source service worker calls registerNavigationRoute() directly, then you'll have to make a chance to your code to get the equivalent behavior.
Instead of:
import {getCacheKeyForURL} from 'workbox-precaching/getCacheKeyForURL.mjs'
import {registerNavigationRoute} from 'workbox-routing/registerNavigationRoute.mjs'
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
You would need to change to:
import {createHandlerForURL} from 'workbox-precaching/createHandlerForURL.mjs'
import {NavigationRoute} from 'workbox-routing/NavigationRoute.mjs'
import {registerRoute} from 'workbox-routing/registerRoute.mjs'
const handler = createHandlerForURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
whitelist: [...],
blacklist: [...],
});
registerRoute(navigationRoute);
(You no longer need to call getCacheKeyForURL(), as createHandlerForURL() will take care of that for you.)
In short, this change makes explicit the two steps that registerNavigationRoute() used to implicitly perform.
matchCallback string/number return values through to handlerCallback. [#2134]In InjectManifest mode, using a .ts file as swSrc and omitting swDest will now lead to a compiled service worker that uses the .js extension. [#2117]
In GenerateSW mode, using a swDest value that included subdirectories will now work as expected. [#2140]
Special thanks to @azizhk and @jaulz for their contributions that went into this release, as well as @derekdowling and @emillundstrm for their issue reports.
The latest alpha release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
The latest alpha release of Workbox v5 includes the following developer-visible changes, in addition to all the changes from the previous pre-release.
All browser-based Workbox packages are now written in TypeScript and type definitions have been published to npm. TypeScript users (as well as users with TypeScript-aware code editors) can now get type checking for all browser-exposed Workbox APIs. (There are no TypeScript definitions for the various Workbox build tools at this time.)
To get type definitions for any Workbox APIs, you can import the package as described in our guide on Using Bundlers (webpack/Rollup) with Workbox. For example:
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {Plugin as ExpirationPlugin} from 'workbox-expiration';
registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
new CacheFirst({
cacheName: 'images',
plugins: [
new ExpirationPlugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
}),
],
}),
);
Note, we've historically published our Workbox source modules with the .mjs extension as a way to disambiguate them from classic scripts and the examples in our documentation that reference file paths always use .mjs.
However, since TypeScript does not currently support importing .mjs files we publish both .js and .mjs files to npm. TypeScript users wanting to import an individual module should be able to reference it by omitting the extension (which will then default to the .js file).
import {registerRoute} from 'workbox-routing/registerRoute';
import {CacheFirst} from 'workbox-strategies/CacheFirst';
import {Plugin as ExpirationPlugin} from 'workbox-expiration/Plugin';
If you encounter any problems with the type definitions or importing the source files via TypeScript, please let us know by opening an issue on GitHub.
Note: The only browser-based Workbox package we haven't converted to TypeScript is workbox-sw, which we don't recommend using with bundlers. As mentioned in the v5.0.0-alpha.0 release notes, our build tools are shifting away from a dependence on a CDN. However, if there are strong use-cases for wanting type definitions for workbox-sw, please let us know, and we can re-evaluate.
node_modules, which could lead to a failed generateSW build process. [#2110]@babel/preset-env configuration during the generateSW build process. [@2113]workbox-windowisUpdate property to the controlling event, which was documented but not actually implemented. [#2114 ]Special thanks to @kaykayehnn for their bug reports and contributions that went into this release.
We're happy to announce the first alpha release of Workbox's v5! This release brings a number of significant changes to all of our build tools: workbo
We're happy to announce the first alpha release of Workbox's v5! This release brings a number of significant changes to all of our build tools: workbox-build, workbox-cli, and workbox-webpack-plugin.
While our immediate plan is to continue publishing copies of the Workbox runtime code to our CDN, in v5, the generateSW mode of our build tools will create a local bundle of exactly the Workbox runtime methods you end up using in your service worker. Depending on the value of inlineWorkboxRuntime, this bundle will either be imported from a separate file, or inlined directly in your top-level service worker.
Under the hood, we use Rollup to create this optimized bundle, optionally minifying it and generating sourcemaps, depending on the configuration.
See #2064 for more details.
If you're using the workbox-webpack-plugin's InjectManifest mode, the service worker file you specify via swSrc will end up being run through a webpack compilation process, optionally applying any compilation plugins configured via the webpackPlugins parameter. This should simplify the development flow described in the Using Bundlers (webpack/Rollup) with Workbox guide.
See #1513 for more details.
You can continue using importScripts('http://storage.googleapis.com/workbox-cdn/releases/5.0.0-alpha.0/workbox-sw.js') and relying on workbox-sw to dynamically pull in the Workbox runtime code that you neeed in v5, but we expect that using a custom bundle will lead to smaller runtime payloads (as well as work around issues with asynchronous imports), and we encourage developers to consider switching off of the CDN.
Before v5, workbox-webpack-plugin would genereate a list of entries to precache based on two distinct sources: the set of assets in a webpack compilation, along with an optional additional set of files matched via glob patterns. Most webpack developers did not use the glob-related options (since the webpack compilation would normally include all the assets that they cared about), but at the same time, some helpful configuration options for manipulating or post-proceessing the precache manifest only applied to entries created via those glob patterns.
In v5, the glob-related configuration options are no longer supported. The webpack asset pipeline is the source of all the automatically created manifest entres. (Developers who have files that exist outside of the webpack asset pipeline are encouragede to use, e.g., copy-webpack-plugin to get those files into the webpack compilation.)
Beyond that, options for post-processing the precache manifest can now be used to manipulate entries that originate from the webpack asset pipeline. manifestTransforms, in particular, can be used to make arbitrary changes to any aspect of the precache manifest, including adding entries, deleting them, and changing their revision or url fields as needed. The current webpack compilation will be passed in to the callback function in case you need information from there to determine how to manipulate entries.
Here's an example of using manifestTransforms to peform extensive post-processing of a precache manifest:
const manifestTransform = (originalManifest, compilation) => {
// If anything needs to be propogated to webpack's list
// of compilaiton warnings, add the message here:
const warnings = [];
const manifest = originalManifest.map((entry) => {
// entry has size, revision, and url fields.
// Add a CDN prefix to certain URLs.
// (alternatively, use modifyURLPrefix)
if (entry.url.endsWith('.jpg')) {
entry.url = `https://examplecdn.com/${entry.url}`;
}
// Remove revision when there's a match for your hashed URL pattern.
// (alternatively, just set dontCacheBustURLsMatching)
if (entry.url.match(/\.[0-9a-f]{6}\./)) {
delete entry.revision;
}
// Exclude assets greater than 1MB, unless they're JPEGs.
// (alternatively, use maximumFileSizeToCacheInBytes)
if ((entry.size > 1024 * 1024) && !entry.url.endsWith('.jpg')) {
warnings.push(`${entry.url} will not be precached because it is too big.`);
return null;
}
return entry;
}).filter(Boolean); // Exclude any null entries.
// When manually adding in additional entries, make sure you use a URL
// that already includes versioning info, like the v1.0.0 below:
manifest.push({
url: 'https://examplecdn.com/third-party-code/v1.0.0/index.js',
});
return {manifest, warnings};
};
Helpers that implement common manifest transformations, like maximumFileSizeToCacheInBytes, dontCacheBustURLsMatching and modifyURLPrefix, are also supported for webpack assets.
See #1591 and #1854.
Additionally, in v5, the precache manifest is inlined into the top-level service worker file, and not stored in a separate, external JavaScript file.
Prior to v4, manifest injection worked by using a regular expression to find the correct location in the source service worker file to replace with the array of manifest entries. This could be brittle, and it was hard to customize, since the replacement step assumed you were using a RegExp that had capture groups.
This is simplifiede in v5, and using the injectManifest mode just checks for a placeholder variable and performs the equivalent of string replacement to inject the full manifest in its place. This variable is self.__WB_MANIFEST by default.
Your swSrc file in v4 might have looked like:
precacheAndRoute([]);
in v5, you should change this to:
precacheAndRoute(self.__WB_MANIFEST);
self.__WB_MANIFEST was choosen as the default replacement because self should always be defined in the service worker global scope, and it is unlikely to conflict with any user-created variables. If you need a different replacement, it can be configured via the injectionPoint option.
See #2059 for more details.
A number of workbox-build, workbox-cli, and workbox-webpack-plugin configuration parameters are no longer supported, following the general outlines of the changes described above. For instance, generateSW will always create a local Workbox runtime bundle for you, so the importWorkboxFrom option no longer makes sense.
We are working on updating the documentation to list the full set of supported options for each mode, but for this alpha, we encourage you to rely on the built-in option validation along with manual inspection of the validation logic if there is any uncertainty.
Thank you for your patience as we get everything documented.
The generateSWString mode has been removed. We expect the impact of this to be minimal, as it was primarily used internally by workbox-webpack-plugin.
The minimum required version of node has been increased to v8.0.0. This also applies to build tools that use workbox-build, like workbox-cli and workbox-webpack-plugin.
webpack v4 or higher.We are using the next tag in npm for the current pre-release version. To install a given module use, e.g., npm install --save-dev workbox-webpack-plugin@next.
Fixed a bug where some private symbols were not being properly exported from workbox-core, which prevented workbox-broadcast-update from notifying on
workbox-broadcast-updateworkbox-core, which prevented workbox-broadcast-update from notifying on navigation requests. [#2050]Adds a new getAll() method to the Queue class. This can be used to get a list of all unexpired entries in a given queue without removing them. This is
workbox-background-syncgetAll() method to the Queue class. This can be used to get a list of all unexpired entries in a given queue without removing them. This is useful in situations where replaying the queue is not possible (the user is offline), but you want to show information about the queue to the user. [#2018]workbox namespace was used before it was defined, when navigationPreload: true. [#2007]broadcastUpdate option in runtimeCaching. [#2017]workbox-background-syncRequest wasn't being clone()ed before re-adding it to the queue. [#2014]mode of same-origin. [#2015]Special thanks to @merrywhether and @tarjei for contributions that went into this release.
Adds a new navigationPreload config property (defaulting to false) to workbox-build's generateSW and generateSWString modes, which would also expose i
navigationPreload config property (defaulting to false) to workbox-build's generateSW and generateSWString modes, which would also expose it to the wrappers like workbox-cli and workbox-webpack-plugin. [#1981]workbox-coreAdds workbox.core.cacheNames.prefix and workbox.core.cacheNames.suffix for accessing the current prefix and suffix used in generating cache names. [#2001]
Adds a new cacheKeyWillBeUsed lifecycle callback. This allows developers to override the default cache key for reads or writes (or both). [#1990]
The interface for the callback looks like:
async function cacheKeyWillBeUsed({request, mode}) {
// request is the default Request object that would otherwise be used as the cache key.
// mode is either 'read' or 'write', depending on whether it's a read or a write.
// Return either a string, or a Request whose url property will be used as the cache key.
// Returning the original request will make this a no-op.
}
workbox-webpack-pluginwebpack loaders [#1966].Special thanks to @merrywhether, @3846masa and @el for contributions that went into this release.
The removeEventListener() method of the Workbox class would throw due to an implementation error, this has been fixed. [#1963]
workbox-windowThe removeEventListener() method of the Workbox class would throw due to an implementation error, this has been fixed. [#1963]
If, at registration time, there was already both an active and waiting service worker with the same script URL as the one being registered, calling getSW() or messageSW() after registration would target the active service worker rather than the waiting service worker. The intended behavior is that the target service worker associated with a Workbox instance is always the most recently registered service worker with a matching script URL. These methods now target the waiting service worker [#1961]
Special thanks to @donavon for contributions that went into this release.
When using the generateSW option to build your service worker, a message listener is now added to the service worker output, which allows you to invok
workbox-buildgenerateSW option to build your service worker, a message listener is now added to the service worker output, which allows you to invoke skipWaiting() from the window via postMessage() [#1929].workbox-windowmessageSW() after an updated service worker is found, it would send the message to the service worker currently controlling the page. This has been fixed [#1941].workbox-precachingcacheDidUpdate method were not properly bound, and would fail in some cases. This has been fixed [#1678].workbox-background-syncIf requests were added to a backgroundSync.Queue queue due to server error rather than network error, those requests would be retried immediately, which could lead to an infinite loop. This has been fixed [#1943]
The backgroundSync.Queue class used to store Request bodies as Blob objects in IndexedDB, but this does not work in Safari. All request bodies are now stored as ArrayBuffer objects [#1932].
workbox-broadcast-updateBroadcastCacheUpdate instance is passed an install event (which happens when using it as a precache plugin) rather than a fetch event, it would error. This has been fixed [#1938].We're happy to announce the release of Workbox version 4! This release introduces a lot of great new features, as well as some breaking changes.
We're happy to announce the release of Workbox version 4! This release introduces a lot of great new features, as well as some breaking changes.
You can read the full list of changes here; we've also published a guide on migrating from v3 to v4.
workbox-windowThe workbox-window package is a set of modules that are intended to run in the window context, which is to say, inside of your web pages. They're a complement to the other workbox packages that run in the service worker.
The key features/goals of workbox-window are:
You can use workbox-window by importing it into your code from our CDN as show in the following example:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/4.0.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
To learn more, see the workbox-window usage guide or the Workbox class reference documentation.
workbox-routingLogging has improved for workbox.routing.NavigationRoute when a URL matches the blacklist. Now a message with higher priority is logged when using the development builds. [#1741]
workbox.routing.Router now includes a routes getter method, giving developers access to the underlying Map of routes that have been registered for a given router. [#1714]
The Router#handleRequest() method no longer requires an event be passed, which allows routing logic to be used programmatically, outside of the context of a fetch event. This can be useful as a way to cache URLs using the same strategies and plugins that you've already defined in your routing logic. [#1682]
workbox-google-analyticsgtm.js library so it will work offline as well [#1869].workbox-broadcast-updateworkbox-broadcast-update plugin now works in browsers that don't support the BroadcastChannel API by iterating over all the open window clients and sending them the update message via postMessage() API. In addition, the channel parameter is no longer required. If no channel is given the default channel name workbox is used (no channle is used for browsers that don't support the BroadcastChannel API). [#1673]boolean configuration option, cleanupOutdatedCaches, has been added to the GenerateSW mode of all of the build tools. It defaults to false. When set to true, a call to workbox.precaching.cleanupOutdatedCaches() will automatically be added to your generated service worker, which will in turn delete any out-of-date precaches no longer used by Workbox. Workbox v4 introduced a breaking change to the precache format, so developers upgrading from Workbox v3 or earlier might find this useful. [#1863]workbox-precachingworkbox-precaching previously could have caused URLs that lead to a HTTP 30x redirect to be cached incorrectly. This is now fixed. [#1678]workbox-expirationworkbox-expiration documentation states that the maxAgeSeconds option will expire entires based on the time they were last accessed. But due to a bug in the logic, it would actually expire entries based on the time they were originally cached. This has been fixed, and the behavior now matches the documentation [#1883].workbox-strategies200, rather than checking for response.ok (which is true for any status code in the range 200-209). In practice, this means that partial responses with a status code of 206 won't be inadvertently cached by default. [#1805]workbox-webpack-pluginswSrc being a file on the file system, it can now be a webpack generated asset as well. This allows users to compile their service worker with webpack and then give it as a source to inject-manifest plugin. [#1763]workbox-coreTo work around an issue that could lead to failed navigations, fetchOptions are no longer set when request.mode is 'navigate'. [#1862]
A new fetchDidSucceed({request, response}) lifecycle callback has been added, allowing developers to inspect and potentially modify a response that's been retrieved from the network, prior to it being passed back to the page. [#1772]
The default injectionPointRegexp option value has been updated to exclude a leading . character, making it friendlier to developers who are bundling their own service worker files. [#1834]
Support has been added for including JavaScript functions when configuring runtimeCaching in the various build tools. [#1770, #1778]
workbox-cli now supports a --watch parameter. When used, it will re-run the service worker build whenever any of the files in the precache manifest change. [#1776]
The workbox-webpack-plugin will append to, rather than overwrite, any existing self.__precacheManifest value, making it easier to combine a precache manifest with the manifest generated by the plugin. [#1775]
As a byproduct of updating our projects various npm dependencies to the latest releases, we've fixed and issue that preventing the workbox-cli's wizard command from properly completing when run on a Windows command line environment. [#1658]
workbox-google-analyticsSome content blocking browser extensions would block requests for script files containing the substring analytics. When these requests are blocked, and error is thrown which causes the service worker installation to fail. To prevent this failure from affecting all service worker functionality, we've renamed the workbox-google-analytics.prod.js and workbox-google-analytics.dev.js to workbox-offline-ga.prod.js and workbox-offline-ga.dev.js. [#1688]
Note: This change is not an attempt to get around content blockers preventing Google Analytics tracking, as requests to all Google Analytics endponts will still be blocked. This change is just to prevent the entire service worker from breaking.
Various public interfaces and options have been renamed to standardize on capitalization. Most noticeably, 'Url' is now 'URL', 'Sw' is now 'SW', and the various strategyName handler values in runtimeCaching are now StrategyName (e.g. 'cacheFirst' is now 'CacheFirst'). The previous capitalization will remain supported until Workbox v5, but using the old variation will lead to deprecation warnings. All developers are encouraged to update their configuration to match the new, consistent capitalization. [#1833, #1841]
The npm names of the following two packages has change to reflect their browser namespace:
workbox-cache-expiration ➡️ workbox-expirationworkbox-broadcast-cache-update ➡️ workbox-broadcast-updateThis change only affects developers who bundle their service worker from npm dependencies. Developers who load Workbox using workbox-sw should not have to change their code. [#1879]
Our @babel/preset-env transpilation targets have been updated to >= node 6 for node libraries and >= Chrome 56 for service worker libraries. Note: we chose Chrome 56 because it matches the capabilities of Samsung Internet v6 and higher. This means we've dropped compatibility with any browser based on Chrome versions earlier than 56, like Samsung Internet v5. [#1655]
workbox-coreworkbox.core.setLogLevel(), workbox.core.logLevel, and workbox.core.LOG_LEVELS have all been removed. [#1831]workbox-strategiesWorkbox previously allowed developers to use workbox-strategies in one of two ways: by calling a workbox.strategies.strategyName() factory method, or by explicitly constructing new workbox.strategies.StrategyName(). To avoid confusion, the workbox.strategies.strategyName() approach is deprecated, and will be removed in v5. We encourage all developers to move to the new workbox.strategies.StrategyName() syntax. [#1831, #1842]
Previously, the various workbox-strategies would behave differently in failure scenarios. Some, like networkFirst, would resolve with an undefined value when there was a network failure and a cache miss. Other strategies would reject with a NetworkError under a similar failure. Starting in v4, we've standardized how all of the workbox-strategies behave when they can't return a response due to some combination of network failure and/or cache miss: the promise that they return will consistently reject with a WorkboxError. This makes it much easier to think about handling failures with "fallback content," making patterns using custom handlers like the following work consistently, regardless of the strategy being used. [#1657]
workbox-precachingworkbox-precaching will default to confirming that all Responses cached during installation have a non-error (less than 400) HTTP status code. If any Responses have an error code, the install phase will now fail. (The next time the service worker starts up, installation will be re-attempted.) Developers who need to precache Responses that have a 4xx or 5xx status code (e.g., precaching a /not-found.html URL that is served with a status code of 404) can opt-in to allowing that by passing in a custom cacheWillUpdate plugin to the workbox.precaching.PrecacheController's install method.
workbox-precaching has undergone a major rewrite [#1820] to address the issues detailed in #1793. As a result, existing precached data used by Workbox prior to this beta release can't be reused, and upon registering a service worker that uses this new code, all precached data will be downloaded again. There is more information in our migration guide detailing specific changes you might need to make to account for the new precaching behavior.
workbox-swworkbox.skipWaiting() has been renamed to workbox.core.skipWaiting(), and workbox.clientsClaim() has been renamed to workbox.core.clientsClaim(). If you are using the skipWaiting or clientsClaim build configuration options, the new method names will be used in your generated service worker automatically.workbox-expirationworkbox-expiration. If you had code that was manually inspected this metadata, you'll need to update it to check the new database [#1883].workbox-background-syncworkbox.backgroundSync.Queue class has been updated to give developers more control over how failed requests are replayed when a sync event occurs. Previously, developers could only add requests to the queue (there was no option to remove them). Now they have low-level methods to push, pop, shift, and unshift requests. For the full list of changes and use cases, see #1710.workbox-range-requestsworkbox-range-requests will now check to see if the Response object it's processing already has an HTTP status code of 206 (indicating that it contains partial content). If so, it will just pass it through unmodified. [#1721]workbox-webpack-pluginworkbox-webpack-plugin will now precache manifest.json by default. Previously, the default configuration would cause workbox-webpack-plugin to exclude files named manfiest.json from the list of files to precache. Because some browsers do in fact make use of the service worker cache when reading the web app manifest data, it makes more sense to default to including, rather than excluding, that file. [#1679]Special thanks to @tanhauhau, @xMokAx, and @tomayac for contributions that went into this release, and to @webmaxru and @jadjoubran for help testing all the pre-releases!
The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
workbox-precachingcacheDidUpdate callback because the now contain a __WB_REVISION__ URL parameter. [#1914]workbox-routingaddCacheListener would throw an error if a message event was received where the event.data property was not an object. [#1913]The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
workbox-windowLifecycle events dispatched by the Workbox class now include an isUpdate property. This property can be used to distinguish lifecycle events in the follow scenarios: 1) the very first service worker installation (isUpdate === undefined), 2) an update from a previous service worker version (isUpdate === true).
The waiting event dispatched by the Workbox class will now include a wasWaitingBeforeRegistration flag in the event that there was already a service worker waiting when the current service worker was registered. When this is true, it typically means there are other open tabs preventing the service worker from activating (or the user is reloading the current tab). See The Service Worker Lifecycle: skip the waiting phase for more details on why this can happen. [#1905]
workbox-routingmessage event listener added via addCacheListener() now no longer requires event.data.metadata to equal workbox-window. This allows developers not using workbox-window to still be able to send cache messages to their service worker. [#1906]The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
workbox-buildcopyLibraries functionality of workbox-build. This has been fixed [#1903].The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
The latest RC release of Workbox v4 includes the following developer-visible changes, in addition to all the changes from the previous pre-releases.
workbox-windowworkbox-window package now ships with a few different build options, to help make it as easy as possible for people to include it in to their existing tool chain [#1895, #1899]. Here's what's currently supported:workbox-window in node (or any or environment that doesn't support native modules):// Imports a UMD version with ES5 syntax
const {Workbox} = require('workbox-window');
workbox-window via webpack or Rollup in a context where your build does not automatically transpile anything in node_modules:// Imports the module version with ES5 syntax
import {Workbox} from 'workbox-window';
workbox-window via webpack or Rollup in a context where you can handle transpiling yourself (or you don't need to transpile to ES5):// Imports the module version with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';
Note: option 3 above will usually result in the smallest file size, so it's recommend to do that if your build supports it.
workbox-routingsetCatchHandler() and setDefaultHandler() methods were not properly migrated as part of the bundling changes in #1831. This has been fixed, and these method now work as they did before [#1898].Your coding agent can read these notes before it upgrades. Set up the MCP server →