← Back to Blog
Illustration of a web app manifest file linked to app icons and a phone home screen install

PWA Manifest Requirements: The Fields Browsers Actually Check (2026)

A browser decides whether your site can be installed by reading one small JSON file. Most "why is there no install button" tickets come down to a missing icon size or a display value the browser ignores — not to anything complicated. This is the current list of what Chromium actually checks, what is optional, and what is a myth.

The required fields

For Chromium browsers — Chrome, Edge, Samsung Internet, Opera — a web app manifest must contain:

Field

Requirement

name or short_name

At least one must be present

icons

Must include a 192px and a 512px icon

start_url

Required

display or display_override

Required

prefer_related_applications

Must be false, or absent entirely

A minimal manifest that satisfies all five:

{
  "name": "Your App Name",
  "short_name": "YourApp",
  "start_url": "/",
  "display": "standalone",
  "icons": [
    { "src": "/icons/192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icons/512.png", "sizes": "512x512", "type": "image/png" }
  ],
  "prefer_related_applications": false
}

Two more conditions live outside the file itself:

  • The page must be served over HTTPS, or from localhost / 127.0.0.1 during development. There is no exception for staging domains on plain HTTP.
  • The manifest must be linked from the page: <link rel="manifest" href="/manifest.webmanifest">, and it must be reachable — a manifest behind auth or blocked by CORS fails silently.

The service worker myth

The most persistent piece of outdated advice is that installability requires a service worker with a fetch handler. That was true of older Chromium versions; it is not a requirement today. A site can be installable with no service worker at all.

That does not make service workers pointless — they are still how you get offline behaviour, caching, and background sync, which is a different goal from being installable. If your reason for adding one was purely to unlock the install prompt, that reason is gone; if it was to keep the app usable on a bad connection, it still stands. We covered the real boundaries of that in PWA offline support.

Fields that are optional but change what users see

These do not gate installability, and they do decide how the install looks:

  • screenshots + description — Chromium shows a richer install dialog, closer to an app store listing, when these are present. Without them users get a plain one-line prompt.
  • id — the stable identity of the app. If you omit it, the identity is derived from start_url; changing start_url later then registers as a different app rather than an update.
  • scope — which URLs stay inside the installed window. Links outside scope open in a browser tab.
  • theme_color / background_color — the toolbar tint and the splash background. A missing background_color gives you a white flash on launch.
  • icons[].purpose: "maskable" — lets Android crop your icon into the platform shape without white borders. Supply a maskable variant in addition to the standard icons, not instead of them.
  • shortcuts — long-press menu entries on the home screen icon.
  • orientation and categories — situational; harmless to include.

Browser support is not uniform

Meeting the Chromium checklist does not mean every browser installs your app the same way.

Platform / browser

Behaviour

Chrome / Edge desktop

Full manifest-driven install

Firefox desktop

No manifest-based install

Android (Chrome, Edge, Firefox, Opera, Samsung Internet)

Supported

macOS Safari (Sonoma and later)

"Add to Dock" — works without a manifest

iOS 16.3 and earlier

Safari only

iOS 16.4+

Safari, Chrome, Edge, Firefox, Orion — via the Share menu

The practical consequence: on iOS the install is a manual user gesture through the Share sheet, so your onboarding has to tell people to do it. There is no programmatic prompt to fire. See how the install prompt behaves across Android and iOS for the flow differences.

How to verify instead of guessing

  1. DevTools → Application → Manifest. Chromium lists the parsed manifest and prints an explicit reason under installability when something is missing.
  2. Lighthouse → Installability audit. Run it against the production URL, not localhost — HTTPS and header problems only appear on the real host.
  3. Fetch the manifest as an anonymous client: curl -I https://yoursite/manifest.webmanifest. Confirm 200 and a JSON content type. A manifest that returns your SPA's HTML shell is the single most common silent failure.
  4. Test on a real Android device. Emulator install behaviour and desktop behaviour both differ from the phone your users hold.

Common reasons a valid-looking manifest still fails

  • Only a 512px icon is declared, or the icons are declared with the wrong sizes string, so the 192px requirement is unmet.
  • display is set to "browser", which explicitly opts out of an app window.
  • start_url returns a redirect to a login page, or sits outside scope.
  • The manifest is served with Content-Type: text/html by a catch-all route.
  • The site is on HTTP, or on HTTPS with a certificate the device does not trust.
  • prefer_related_applications is true, left over from a template that pointed at a native app listing.

If you are still deciding whether an installable web app is the right distribution route at all, the trade-offs against packaged Android distribution are in PWA vs APK, and the difference from a Trusted Web Activity is in PWA vs TWA.

Frequently asked questions

Does a PWA need a service worker to be installable?

No. Current Chromium installability rules do not require a service worker. You still need one for offline support, caching, and background features — those are separate goals from installability.

Which icon sizes are actually required?

A 192px and a 512px icon. Additional sizes and a maskable variant are recommended for icon quality on Android, but they are not part of the requirement.

Can a PWA be installed over HTTP?

Only from localhost or 127.0.0.1 for local development. Any other host must serve over HTTPS with a valid certificate.

Why is there no install prompt on iPhone?

iOS does not expose a programmatic install prompt. Users add the app from the Share menu — Safari on all supported versions, and Chrome, Edge, Firefox or Orion on iOS 16.4 and later. Your UI has to guide that gesture.

Does changing start_url break my installed app?

It can. Without an explicit id, app identity is derived from start_url, so changing it makes browsers treat the result as a new app rather than an update to the installed one. Set id early.

ROIBest

Build your next growth engine with ROIBest

Talk to our team about a stable, high-converting Android PWA solution.