Skip to content

Manifest member in Manifest

scope manifest member

Published Updated

Limited availabilityNot supported in Firefox (Desktop)W3C

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.

  • Type: string holding a URL, absolute or relative; a relative value resolves against the manifest file’s URL, not the document’s.
  • Default: start_url with its filename, query, and fragment removed. start_url of /app/index.html?user=1#home gives 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.

Each example pairs a manifest with the page-level consequence it has.

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.

Specifications

SpecificationStatus
Web App Manifest: scopeW3C
Web Application Manifest: within scopeW3C
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Android)Yes73mediumsource—
Chrome (Desktop)Yes73mediumsource—
Edge (Desktop)Yes79mediumsource—
Safari (iOS)Yes16.4mediumsource1
Safari (macOS)Yes17mediumsource2
Firefox (Desktop)No—mediumsource3
Samsung InternetYes6.2mediumsource—
  1. Honored for home-screen web apps; off-scope navigation surfaces a banner rather than a full address bar.
  2. Applies to Dock-installed web apps.
  3. No manifest-based install path, so scope is not applied.

Ecosystem & commercial policy

EntityTypeContextStatusSponsoredNotes
Google Play (TWA)distribution_channelGoogle Play TWAYesNoassetlinks.json origin must match the manifest scope origin, or the TWA degrades to a Custom Tab with browser chrome.
Microsoft Store (PWA)distribution_channelMicrosoft StoreYesNoScope defines the in-app boundary store reviewers preview at submission.

Source data: /compatibility/manifest-scope.json · Global usage: 90 % (StatCounter 2026-05)

Source: spec · MDN · Last verified 2026-06-24 · Confidence: medium (computed from sources)