Manifest member in Manifest
scope manifest member
Published Updated
scope is a URL string naming the navigation scope of an installed web app: the set of pages
that get the app-like window without browser controls. A URL is within scope when it is same
origin as the scope URL and its path begins with the scope URL’s path; everything else is out of
scope and is still reachable, but the browser restores its own UI to say so.
Chrome 73 (Android and desktop), Edge 79, Samsung Internet 6.2, Safari 16.4 on iOS, and Safari 17
on macOS apply the member to installed apps (BCD html.manifest.scope). Firefox 157 on desktop
has no manifest-based install path, so the value has no consumer there. On Android the same
string also decides which links an installed WebAPK captures from other apps.
Member
Section titled “Member”- Type: string holding a URL, absolute or relative; a relative value resolves against the manifest file’s URL, not the document’s.
- Default:
start_urlwith its filename, query, and fragment removed.start_urlof/app/index.html?user=1#homegives an effective scope of/app/. - Example value:
"/app/".
Two rules drop the member and fall back to the default. The scope must be same origin as the
document (property 'scope' ignored, should be same origin as document.), and start_url must
be within the scope (property 'scope' ignored. Start url should be within scope of scope URL.).
Both messages come from Chromium’s manifest_parser.cc.
Matching is a plain string prefix on the path, not a directory test. "/app" matches
/app-admin/ and /application.html as well as /app/; end the value with / to confine it
to one directory. Scope is not a security boundary: an out-of-scope navigation is not blocked,
and the service worker’s scope is a separate value set at register() time (MDN,
ServiceWorkerRegistration.scope) that can be wider or narrower than the manifest’s.
What out-of-scope looks like differs by platform. Chrome on Android opens the page in a custom-tab
style view with the URL shown at the top; Chrome and Edge on desktop add a toolbar with the origin
and an “open in browser” control; Safari 16.4 on iOS shows a banner inside the home-screen app
rather than a full address bar (BCD note). Cross-origin pages can be pulled into scope only with
scope_extensions.
Examples
Section titled “Examples”Each example pairs a manifest with the page-level consequence it has.
Confining the app to a subpath
Section titled “Confining the app to a subpath”A dashboard served under /app/ on a site whose marketing pages live at the root. Links to
/pricing/ open in the app window with browser controls restored, so the visitor can tell they
have left the app.
{ "name": "Ledger", "start_url": "/app/", "scope": "/app/", "display": "standalone"}The trailing slash matters: "scope": "/app" would also claim /app-status/ and
/apply.html because matching is a path-prefix comparison.
Letting the default scope derive from a start_url with a query
Section titled “Letting the default scope derive from a start_url with a query”A manifest that tags launches with a query string and declares no scope. The browser strips the
filename, query, and fragment from start_url, so the effective scope is /app/ and the whole
directory is in scope, including the untagged /app/ URL the user reaches by navigation.
{ "name": "Ledger", "start_url": "/app/index.html?source=homescreen", "display": "standalone"}If the same manifest had "start_url": "/app/index.html?source=homescreen" and
"scope": "/dashboard/", the scope would be dropped (start URL not within it) and /app/ would
again be the effective scope; the mistake is silent except for the DevTools line quoted above.
Detecting an out-of-scope context at runtime
Section titled “Detecting an out-of-scope context at runtime”The manifest’s scope is not exposed to script, but the display-mode media feature reports
whether the current page is being shown with browser UI. In an installed app that means the page
is out of scope (or the user opened it in a tab); in an engine without the feature the query
matches nothing and the code takes the same fallback branch as a browser tab.
function isWithinScope(target, scope) { const t = new URL(target, location.href); const s = new URL(scope, location.href); return t.origin === s.origin && t.pathname.startsWith(s.pathname);}
const APP_SCOPE = '/app/';const inAppWindow = matchMedia('(display-mode: standalone)').matches;
if (!inAppWindow || !isWithinScope(location.href, APP_SCOPE)) { // Browser tab, unsupported engine, or an out-of-scope page: show the full site header. document.documentElement.dataset.chrome = 'site';} else { document.documentElement.dataset.chrome = 'app';}Keep APP_SCOPE in one constant shared with the manifest build so the two cannot drift; the
browser gives no warning when they do.
See also
Section titled “See also”- start_url manifest member
- scope_extensions manifest member
- display manifest member
- Service worker registration and scope
- PWAs on Chrome and Android (WebAPK, TWA)
- Web Application Manifest: scope member (w3.org)
- WebAPKs on Android (web.dev)
Specifications
| Specification | Status |
|---|---|
| Web App Manifest: scope | W3C |
| Web Application Manifest: within scope | W3C |
- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Android) | Yes | 73 | medium | source | — |
| Chrome (Desktop) | Yes | 73 | medium | source | — |
| Edge (Desktop) | Yes | 79 | medium | source | — |
| Safari (iOS) | Yes | 16.4 | medium | source | 1 |
| Safari (macOS) | Yes | 17 | medium | source | 2 |
| Firefox (Desktop) | No | — | medium | source | 3 |
| Samsung Internet | Yes | 6.2 | medium | source | — |
- Honored for home-screen web apps; off-scope navigation surfaces a banner rather than a full address bar.
- Applies to Dock-installed web apps.
- No manifest-based install path, so scope is not applied.
Ecosystem & commercial policy
| Entity | Type | Context | Status | Sponsored | Notes |
|---|---|---|---|---|---|
| Google Play (TWA) | distribution_channel | Google Play TWA | Yes | No | assetlinks.json origin must match the manifest scope origin, or the TWA degrades to a Custom Tab with browser chrome. |
| Microsoft Store (PWA) | distribution_channel | Microsoft Store | Yes | No | Scope defines the in-app boundary store reviewers preview at submission. |