Skip to content

The WorkboxLifecycleEvent.isUpdate is false on first immediate service worker updateΒ #3377

Open
@piotr-cz

Description

@piotr-cz

Library Affected:
workbox-window

Browser & Platform:
At least Chrome 131.0.6778.86, possibly all browsers

Issue or Feature Request Description:

The WorkboxLifecycleEvent.isUpdate will remain false in following scenario:

  1. New service worker installation
  2. Alter source code to trigger update in next step
  3. Manually trigger Service worker update (without navigation/ page reload), for ie. by one of;
    • DevTools > Application > Service workers > Update
    • (await navigator.serviceWorker.getRegistration()).update()

This matches the behavior described in source:

* @property {boolean|undefined} isUpdate True if a service worker was already
* controlling when this service worker was registered.

However it's name leads to false assumption that it's value is true on any update (even that there was no controlling service worker at the time of registration).

Some examples:

  • chrome for developers > Workbox-window docs > When an updated version of the service worker is found:

    When a new service worker starts installing but an existing version is currently controlling the page, the isUpdate property of all the following events will be true.

  • web.dev > Broadcast updates to pages with service workers > Listen to service worker lifecycle events

    wb.addEventListener('installed', (event) => {
      if (event.isUpdate) {
        // Show "Update App" banner
      }
    });
  • demos > workbox-window

    wb.addEventListener('activated', (event) => {
    // `event.isUpdate` will be true if another version of the service
    // worker was controlling the page when this version was registered.
    if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

Suggested solution

I think the fix is to set this._isUpdate = true after first installation:

diff --git a/packages/workbox-window/src/Workbox.ts
    private readonly _onControllerChange = (originalEvent: Event) => {
      const sw = this._sw;
      const isExternal = sw !== navigator.serviceWorker.controller;

+     this._isUpdate = true
+     this._isUpdate = navigator.serviceWorker.controller !== null // Alternative implementation

and adjust jsdoc comments for this property.

I'm just not entirely sure if this is the right place?

Related PR: #1905

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions