When a broken build of an Angular app is stuck in users' browsers through @angular/service-worker, how do the ngsw.json fail-safe and safety-worker.js remove it?
answer
- a 404 for the manifest
- self-destruct and clear caches
- serve at the old worker URL
- never register it directly
- keep serving it
basics
~10 sIf ngsw.json returns 404, the Angular worker deletes its caches and unregisters itself; safety-worker.js, served at the old worker script URL, unregisters any worker and removes caches for clients that cannot otherwise be reached.
solid answer
~40 sThe Angular worker has a built-in **fail-safe**: when its request for `ngsw.json` returns `404`, it removes all its caches and unregisters itself. Renaming or deleting `ngsw.json` on the server is therefore a kill switch for the Angular worker. For a harder case, such as a moved site or a different worker, `@angular/service-worker` ships `safety-worker.js`, which unregisters itself and clears the caches when it runs. You must **not** register it from new code, because stuck clients never load new `index.html`; instead serve its contents **at the old worker's script URL**, so the browser's own update check installs it. Keep serving it until you are sure every client has unregistered; for most sites that means forever. Usually, though, simply redeploying a fixed build is enough, because the next `ngsw.json` check picks it up.
go deeper
Recall that deleting ngsw.json makes the Angular worker remove itself, and that safety-worker.js exists for harder cases.
Explain the 404 fail-safe and why the safety worker is served at the old script URL instead of registered.
Pick the right recovery for the incident, including redirects and site moves, and keep the safety worker served long enough.
Plan service worker exit and migration strategy before adopting it, including a standing kill switch and its ownership.
## When you need a kill switch Most bad releases do not need one: deploy a fixed build and the Angular worker picks it up at its next `ngsw.json` check and serves it on the following load. A kill switch is for cases where the worker itself is the problem: - the worker keeps serving a broken version, or clients are in a degraded state you cannot fix by deploying; - you are **removing** the service worker from the app; - the app **moved** to another origin or path and the old worker is behind a redirect (service worker scripts behind a redirect are disallowed, so the old worker can no longer update itself). `@angular/service-worker` offers two mechanisms. ## The ngsw.json fail-safe The Angular worker regularly requests `ngsw.json`, the manifest describing the current version. The documented behaviour: - if that request returns **`404`**, the worker **removes all its caches and unregisters itself**, effectively self-destructing; - so **renaming or deleting `ngsw.json`** on the server deactivates the Angular worker for clients as they check in. It is simple and needs no new code. Its limits: it only works while clients can still reach the manifest at the same location, and it only affects the Angular worker. ## The safety worker `safety-worker.js` is a small script included in the `@angular/service-worker` package. When it runs as a service worker, it **unregisters itself** from the browser and **removes the service worker caches**. It also removes other service workers that were served on the site in the past. How to deploy it matters more than what it does: 1. **Do not register it from application code.** Stuck clients are served the old cached `index.html`, so they never run new registration code. 2. **Serve its contents at the URL of the worker you want to remove**, for example at `/ngsw-worker.js`. The browser periodically re-fetches the registered worker script, sees different bytes, installs the safety worker, and it cleans up. 3. **Keep serving it** until you are sure every client has unregistered. The documentation's advice is that for most sites this means serving the safety worker at the old URL **forever**, because a client that has been away for a year still carries the old registration. ## Choosing between them | Situation | Mechanism | |---|---| | A normal bad release | Deploy the fix; no kill switch needed | | Turning off the Angular worker, same location | Remove or rename `ngsw.json` (fail-safe) | | Moved site, redirects, or unknown older workers | `safety-worker.js` at the old worker URL | | Removing service workers permanently | Safety worker, served indefinitely | ## Things that go wrong - **Registering the safety worker under a new URL** only affects clients that load new HTML, which stuck clients do not. - **Deleting `ngsw.json` while the app still enables the worker**: the next build emits a new `ngsw.json` and new HTML registers the worker again, so turning it off also means removing `provideServiceWorker()` or setting `enabled: false`. - **Stopping too early**: taking the safety worker down after a week leaves long-absent users stuck. - **Relying on user action**: asking users to clear site data does not scale. ## Degraded states are not the same as broken Before reaching for a kill switch, check whether the worker has already protected users by itself. The `ngsw/state` page reports the **driver state**: - `NORMAL`: operating as designed; - `EXISTING_CLIENTS_ONLY`: the worker has no clean copy of the latest version, so existing tabs keep running from cache while new loads come from the network, and it recovers when a new `ngsw.json` is installed; - `SAFE_MODE`: the worker cannot trust its cache, so all traffic goes to the network with as little worker code as possible. Both degraded states are temporary and last only for the life of that worker instance. A worker that falls back to the network like this is often better fixed by a clean redeploy than by removing it. ## After recovery Once clients are clean, re-enabling service worker support is an ordinary deploy with a registered worker. The `/ngsw/state` debug page of a still-running Angular worker is useful before pulling a kill switch, to see whether the worker is in a degraded mode rather than broken.
- Why can't you fix stuck clients by registering safety-worker.js from the new index.html?Stuck clients are served the old cached `index.html` by the old worker, so they never execute the new registration code. Serving the safety worker's bytes at the old worker's script URL works because the browser itself re-fetches that URL during update checks and installs the changed script.
- What does renaming ngsw.json on the server do to clients running the Angular worker?When the worker next requests `ngsw.json` and gets a `404`, it deletes all its caches and unregisters itself. Later loads go straight to the network. It is the lightest kill switch, but it only helps clients whose worker can still reach the manifest.
saying these in an interview costs you the question
- You register safety-worker.js from the new application code
- A 404 for ngsw.json makes the worker keep serving its last version forever
- The safety worker can be removed after a few days
- Every bad release requires the safety worker
- Clearing the server's CDN cache also clears users' service worker caches