Skip to content

Concept in Service Worker

Service-Worker-Allowed header

Published Updated

Widely available since 2018-04W3C draft

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.

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

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.

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

Section titled “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.

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.

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.

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: '/' }.

Specifications

SpecificationStatus
Service WorkersW3C draft
Service Workers: Service-Worker-AllowedW3C draft
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Desktop)#Yes40highsource—
Chrome (Android)#Yes40highsource1
Edge (Desktop)#Yes17highsource—
Firefox (Desktop)#Yes44highsource—
Firefox (Android)#Yes44highsource2
Safari (macOS)#Yes11.1highsource—
Safari (iOS)#Yes11.3highsource3
Samsung Internet#Yes4.0highsource4
WebView (Android)#Yes40highsource5
  1. Derived by browser-compat-data mirroring from Chrome.
  2. Derived by browser-compat-data mirroring from Firefox.
  3. Derived by browser-compat-data mirroring from Safari.
  4. Derived by browser-compat-data mirroring from Chrome Android.
  5. Derived by browser-compat-data mirroring from Chrome Android.

Source data: /compatibility/service-worker.json · Global usage: 96 % (StatCounter 2026-09, CC BY-SA 4.0)

Source: spec · MDN · Last verified 2026-10-20 · Confidence: high (computed from sources)