web app manifest

Web App Manifest — Live Demos

checking install state…

manifest.json builder

Fill the fields and copy a valid manifest plus the <link> tag. Required fields for installability are marked.

manifest.json
Link it in your <head>:
<link rel="manifest" href="/manifest.json">
Serve with application/manifest+json MIME type.
--:--:--Edit fields → the manifest regenerates live

Install experience — display modes side by side

See how the same app launches with each display mode and theme_color. Only standalone/fullscreen/minimal-ui count as "installed".

9:41▲ ▼ 100%
w3tweaks.com
W3Tweaks
Advanced HTML Tutorials
--:--:--Switch modes — watch the browser chrome appear/disappear

Maskable icons & the safe zone

Platforms crop icons to different shapes. A non-maskable icon gets a white box; a maskable one keeps content inside the safe zone (a circle of radius 40% of the width).

icon is purpose: "maskable" (content padded into the safe zone)
show the 40% safe-zone ring
{ "src": "/maskable-512.png", "sizes": "512x512", "purpose": "maskable" }
--:--:--Toggle maskable off to see the white-box problem

Custom install button (beforeinstallprompt)

The real flow: capture beforeinstallprompt, stash it, show your own button, and call .prompt() on click. This page tries the real event; if unavailable, it simulates it.

Waiting for installability…
// capture & defer, then prompt on YOUR button click let deferred = null; window.addEventListener('beforeinstallprompt', e => { e.preventDefault(); // suppress mini-infobar deferred = e; // stash for later installBtn.hidden = false; }); installBtn.addEventListener('click', async () => { deferred.prompt(); // in a user gesture const { outcome } = await deferred.userChoice; deferred = null; // single-use });
⚠ Chromium-only. iOS Safari never fires this — show iOS users a manual "Share → Add to Home Screen" hint instead.
--:--:--Waiting for the real beforeinstallprompt event…

Installability validator

Paste a manifest (or use the sample). Checks required fields, icon sizes, start_url-in-scope, display mode, and the maskable-icon recommendation.

--:--:--The sample has 4 issues — click Validate to find them