Skip to main content
The ServiceWorkerService manages Progressive Web App (PWA) updates through Angular’s service worker. It monitors version changes, notifies users of available updates, and tracks update check timestamps.

Location

src/app/services/service-worker/service-worker.service.ts

Properties

lastUpdateCheckTimestamp
Signal<string>
Read-only signal containing the ISO timestamp of the last update check. Persisted to localStorage.

Methods

checkForUpdate()

Manually checks for available updates. If an update is already downloaded and ready, prompts the user to reload immediately.
const hasUpdate = await serviceWorkerService.checkForUpdate();
if (hasUpdate) {
  console.log('Update is available or ready');
}
Returns: Promise<boolean> - true if an update is available or ready

Update Flow

The service automatically handles the complete update lifecycle:
1

Version Detection

When a new version is detected, shows an alert: “Downloading updates…”Analytics event: version_detected
2

Download & Installation

Service worker downloads and installs the new version in the background
3

Version Ready

Shows alert with reload button: “Reload to update”Analytics event: version_ready
4

User Action

User clicks reload button → window.location.reload() → New version activates

Version Events

The service subscribes to Angular’s SwUpdate.versionUpdates and handles:

NO_NEW_VERSION_DETECTED

  • Updates lastUpdateCheckTimestamp
  • Logs analytics event: no_new_version_detected

VERSION_DETECTED

  • Updates lastUpdateCheckTimestamp
  • Shows “Downloading updates…” alert
  • Logs analytics event with version hash

VERSION_READY

  • Sets internal isUpdateReady flag
  • Shows “Reload to update” alert with action button
  • Logs analytics event with current and latest version hashes

VERSION_INSTALLATION_FAILED

  • Logs error with LoggerService
  • Shows error alert to user
  • Logs analytics event: version_installation_failed

Usage in Settings Page

The SettingsPageComponent allows users to manually check for updates:
import { inject } from '@angular/core';
import { ServiceWorkerService } from '@jet/services/service-worker/service-worker.service';

export class SettingsPageComponent {
  readonly serviceWorkerService = inject(ServiceWorkerService);

  async onCheckForUpdateClick() {
    await this.serviceWorkerService.checkForUpdate();
  }
}
<p>
  {{ t('settings-page.last-checked-for-updates-on') }}
  {{ serviceWorkerService.lastUpdateCheckTimestamp() | date: 'medium' }}
</p>
<button mat-flat-button (click)="onCheckForUpdateClick()">
  {{ t('settings-page.check-for-updates') }}
</button>

Configuration

Service worker configuration is defined in ngsw-config.json:
{
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": ["/favicon.ico", "/index.html", "/*.css", "/*.js"]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": ["/assets/**", "/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"]
      }
    }
  ]
}

Persistence

The lastUpdateCheckTimestamp is automatically persisted to localStorage using an Angular effect:
effect(() => {
  const timestamp = this.#lastUpdateCheckTimestamp();
  untracked(() => 
    this.#storageService.setLocalStorageItem(
      LocalStorageKey.LastUpdateCheckTimestamp, 
      timestamp
    )
  );
});

Best Practices

Automatic Update Checks: The service worker automatically checks for updates on page load and periodically. Manual checks are optional.
Reload Required: Updates only take effect after a full page reload. Users must click the reload button or refresh the page.
Update Frequency: Consider displaying the last update check timestamp so users know when the app last checked for updates.

Build docs developers (and LLMs) love