A companion to the FieldKit series, where I built one real Progressive Web App to explore what modern PWAs can do (code on GitHub). The app is "done" and passes Chrome's install criteria — but passing and correct aren't the same thing. Here I audit FieldKit with a one-click tool, find a subtle manifest issue, and fix it properly.
"It installs" is not the same as "it's right"
Across the FieldKit series I kept saying the same thing: on the web, the happy path is easy and the details are where you earn your keep. The manifest is a perfect example. FieldKit installs fine — Chrome's criteria are met — but "meets the criteria" leaves out a whole layer of correctness that only bites you later, in production, with real installed users.
So instead of eyeballing DevTools, let me audit FieldKit with a dedicated tool and act on what it finds.
The 30-second audit
I use a small Chrome extension for this, the PWA & Installability Inspector. Full disclosure: it's mine, and it's open source (MIT) — I built it while working through this exact series because I got tired of manually cross-checking manifest fields. Click it on any site and it gives a verdict plus a checklist of what passed, what's missing, and how to fix it. DevTools → Application → Manifest does the same job by hand; this just makes the loop instant.
Here's FieldKit under inspection:
The verdict is green — Installable — and every hard requirement passes:
- Served over HTTPS (or localhost)
- Page links a web app manifest
- Manifest has
nameorshort_name - Manifest has an installable
displaymode - Manifest has a
start_url - A 192px (or larger) icon is available
- A 512px (or larger) icon is available
- A service worker controls the page
Zero errors. But one warning — and it's the interesting kind, the sort DevTools' green checkmark quietly ignores.
The warning: "Manifest is missing 'id'"
⚠️ Manifest is missing "id" — Stable app identity independent of
start_url.
This isn't a "your app is broken" warning. FieldKit installs and runs fine without it. It's a "you're building on sand" warning — and understanding why is worth more than the one-line fix.
What id actually is
Every installed PWA needs a stable identity so the browser can tell "this is the app I already installed" from "this is a new app to install." The id field (Chrome 96+) is that identity.
The catch is what happens when you don't set it: if id is absent, the browser falls back to using your start_url as the identity. And that's a trap, because start_url is something you might reasonably want to change — for a new campaign, a different landing screen, an analytics tweak. The moment you change a start_url that's doubling as your identity, the browser thinks it's looking at a brand-new app. Your existing users' installed copy is orphaned, updates stop reaching it, and a duplicate can appear. All from what looked like a harmless URL edit.
Setting an explicit id decouples identity from start_url, so you can change the start URL later without breaking a single install. That's the whole point of the warning.
The fix — and the part you must get right
The one-line answer is "add an id." But which value you pick matters enormously, and this is where people quietly break their app.
FieldKit's start_url is "/?source=pwa". Because we never set an id, the browser has already been using "/?source=pwa" as FieldKit's identity for anyone who installed it. So the safe fix is to make the new explicit id match that existing identity:
{
"name": "FieldKit — Offline Field Notes",
"short_name": "FieldKit",
"id": "/?source=pwa",
"start_url": "/?source=pwa",
"scope": "/"
}
Add the id, re-run the inspector, and the warning clears:
A couple of details worth knowing:
-
idis resolved as a URL relative to your origin, not tostart_url. So"/?source=pwa"becomeshttps://yourdomain.com/?source=pwa. You can check the computed value inchrome://appsor via the inspector. - It does not have to equal
start_url— but when you're addingidto an app that's already in the wild, matching the currentstart_urlis how you avoid changing the identity out from under existing installs.
How to change an id correctly (mostly: don't)
Since the reader asked, and it's the genuinely dangerous part: the correct way to change a manifest id is, almost always, to not change it.
The id is meant to be permanent. It is the primary key of your app. Changing it doesn't "rename" your app — it tells every browser that this is a different app entirely:
- installed users keep the old app, which no longer receives your updates;
- your new
idinstalls as a separate app, so you can end up with duplicates; - there is no "migrate identity" mechanism — a changed
idis a new app, full stop.
So the practical rules:
-
Set
idonce, early, and treat it as immutable. Pick something short and stable like"/?source=pwa"(or"/"for a greenfield app) and never touch it again. -
When adding
idto an existing app, match the currentstart_urlso you preserve the identity the browser already assigned. (That's exactly what we did for FieldKit.) -
Once
idis set, you're free to changestart_url, the manifest's location, scope entry point, etc. — that new freedom is the entire benefit. Change those, never theid. - If you must re-identify an app (a genuine rebrand to a new domain, say), accept that it's a new install and communicate the migration to users — don't expect the platform to bridge it.
Think of it like a database primary key: you can change every other column, but you don't rewrite the key of a live row and expect the foreign references to follow.
The takeaway
FieldKit passed Chrome's install criteria from day one, yet still shipped a latent foot-gun: an identity implicitly tied to a URL I might have changed later. A 30-second audit surfaced it, and a one-line fix — with the right value — future-proofed it. That gap between "passes" and "correct" is exactly where auditing tools earn their place in your workflow.
The popup is just the summary. Hit Full report for the deep dive — every manifest field validated individually, icon and service-worker details, and the advanced-capabilities (Fugu) breakdown showing which APIs the browser supports versus which the page actually uses. It's where you go from "no warnings" to genuinely understanding your app's install profile:
Audit your own PWA (the inspector is here), and FieldKit's whole manifest is on GitHub if you want to see the fixed version in context.




Top comments (0)