# Service-Worker-Allowed header

> Service-Worker-Allowed sets the maximum path scope a service worker script may request beyond its own directory.

The `Service-Worker-Allowed` HTTP response header lets a service worker registration
request a scope beyond the script's directory. Return it with the script to set the
maximum allowed scope path.

## Browser and platform support

Service worker registration requires a secure context, as specified by Service Workers.

## How it works

Without the header, the Service Workers specification derives the maximum allowed scope from the
script URL's directory. A script at `/product/sw.js` therefore has `/product/` as its default
maximum. Returning `Service-Worker-Allowed: /` with that script lets a registration request `/`.

The header value is a URL parsed relative to the script URL. The specification compares the
requested scope path with that maximum path. A requested scope path that does not start with the
maximum allowed path, or a header URL whose origin differs from the script URL, causes the
registration job to reject with a `SecurityError`. If parsing the header value as a URL fails, the
fetch completes with a network error; the update algorithm later rejects the job with a `TypeError`
unless a `SecurityError` was already invoked.

:::security
The Service Workers specification says the path restriction helps sites that host different users'
content in separate directories on one origin. It also says paths are not a hard security boundary;
use different origins when site segments require secure isolation.
:::

:::caution
Chromium's `service_worker_loader_helpers.cc` builds this exact sentence when `/product/sw.js` requests the scope `/` without an enabling header ([Chromium source](https://github.com/chromium/chromium/blob/main/content/browser/service_worker/service_worker_loader_helpers.cc)):
`The path of the provided scope ('/') is not under the max scope allowed ('/product/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.`
:::

## Examples

The server must attach the header to the service worker script response, not to the page that calls
`register()`. The client can then request the matching wider scope.

### Serve the script with a root maximum scope

This Node HTTP handler returns the header with `/product/sw.js`. The service worker body is valid
JavaScript and installs without adding cache entries.

```js
import { createServer } from 'node:http';

createServer((request, response) => {
  if (request.url === '/product/sw.js') {
    response.writeHead(200, {
      'content-type': 'text/javascript',
      'service-worker-allowed': '/',
    });
    response.end("self.addEventListener('install', () => {});");
    return;
  }

  response.writeHead(404);
  response.end('Not found');
}).listen(8080);
```

With this response, the specification permits `/product/sw.js` to request `/` as its registration
scope.

### Register the wider scope with a fallback

Check for service worker support before registering. If registration rejects, keep the page
online-only and report the deployment error without assuming that the worker controls the page.

```js
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/product/sw.js', { scope: '/' })
    .then((registration) => {
      console.log('Registered scope:', registration.scope);
    })
    .catch((error) => {
      console.error('Service worker registration failed:', error);
      document.documentElement.dataset.offline = 'unavailable';
    });
} else {
  document.documentElement.dataset.offline = 'unsupported';
}
```

The requested scope must stay within the maximum named by the header. For example,
`Service-Worker-Allowed: /product/` does not permit `{ scope: '/' }`.

## See also

- [Service worker registration and scope](/reference/service-worker/registration-scope/)
- [Service worker lifecycle](/reference/service-worker/lifecycle/)
- [Debugging service workers](/reference/service-worker/debugging/)
- [Service Workers: Service-Worker-Allowed](https://w3c.github.io/ServiceWorker/#service-worker-allowed) (w3c.github.io)
- [Service-Worker-Allowed header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Service-Worker-Allowed) (MDN)