The manifest is a JSON file that describes your web app to the browser. The builder writes one for you; this guide is so you understand what it wrote and can change it with confidence. Fields are grouped by what they affect.
Identity
name
The full name. Shown on the install prompt, the splash screen and in settings. Up to about 45 characters display; longer is truncated. Use your brand as people know it: "Rosie's Bakery", not "Rosie's Bakery — Order Online".
short_name
Shown under the icon on home screens, where space is 11–12 characters before truncation. "Rosie's" beats "Rosie's Bakery". If you omit it, name is used and will likely be cut mid-word.
description
A sentence or two, shown in Chrome's richer install dialog (when screenshots are present) and used by Google Play for TWAs. Say what the app does for the user.
id
A stable identifier for the app, relative to the origin — e.g. "/" or "/app". Browsers use it to recognise the same app across manifest changes. Set it once and never change it; if you later change start_url, the id is what stops the browser treating your app as a new one. Older manifests without id default to start_url, which is why changing start_url used to "un-install" apps.
Where it opens
start_url
The page opened from the icon. Usually / or a dedicated app landing such as /app. Add a query string (/?source=pwa) to distinguish installed launches in analytics. Must be same-origin as the manifest and inside scope.
scope
The URL prefix that counts as "inside the app". Navigations within scope stay in the app window; navigations outside it open in a browser (a Custom Tab on Android). Set it to / for a whole site, or /app/ to exclude, say, your marketing pages. A scope that is too narrow is a common cause of "my app keeps opening the browser".
How it looks
display
| Value | Effect | Use for |
|---|---|---|
standalone | Own window, no browser UI, status bar visible | Almost everything |
fullscreen | Also hides the status bar | Games, kiosks. Falls back to standalone where unsupported (iOS) |
minimal-ui | Own window with back/reload controls | Rare; Android only |
browser | Normal tab | Disables installability — don't |
orientation
portrait, landscape, any, and their primary/secondary variants. Locks the installed app on Android and desktop; ignored by iOS Safari. Only lock what your layout truly supports.
theme_color
Colour of the status bar and window title bar. Needs legible contrast for white or black system text — see the palette tool. The page-level <meta name="theme-color"> overrides it per page and can vary by colour scheme.
background_color
Colour of the generated splash screen while the first page loads. Match your page background so the transition is seamless.
Icons
icons
An array of { src, sizes, type, purpose }. Requirements for installability: at least one 192×192 and one 512×512 PNG. Best practice:
"icons": [
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icons/maskable-192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]purpose: "maskable" tells Android it may crop the icon into its launcher shape; the icon must have padding for that (the safe zone is a circle 80% of the width). Marking an unpadded icon maskable clips it. The icon resizer previews the masks. iOS ignores this array and uses <link rel="apple-touch-icon"> instead.
Richer install UI
screenshots
An array of images with form_factor (narrow for phone, wide for desktop), sizes, type and a label. When present, Chrome shows a store-like install dialog with a carousel. Constraints: 320–3840 px per side, same aspect ratio within a form factor, at least one per form factor you want covered. The screenshot tool exports at compliant sizes.
categories
Free-text hints like ["shopping"] or ["games"]. Used by some install surfaces and stores; harmless to include.
Shortcuts and more
shortcuts
Long-press menu items on the app icon (Android, desktop): up to four { name, url, icons } entries such as "Order again" or "My account". Cheap to add, noticeably app-like.
related_applications and prefer_related_applications
Point at your Play Store listing if you have a native app and want Chrome to suggest it instead of installing the PWA. If you are the PWA, leave prefer_related_applications false or absent — setting it true suppresses the PWA install prompt.
lang, dir
Language and text direction of the manifest's strings. Set lang to your site's language code.
Linking it
<link rel="manifest" href="/manifest.json">Serve it with Content-Type: application/manifest+json (or application/json, which browsers accept). Cross-origin manifests work if served with CORS and the crossorigin attribute; the start_url must still be on your origin.
Checking your work
Chrome DevTools → Application → Manifest shows the parsed manifest, the icons as the browser sees them, the maskable preview, and — under Installability — the exact reason a prompt is not appearing. It is the single most useful debugging view for this whole topic.