Installability

Installability means the browser or store can present the web app like an app: icon, launch surface, app window, and platform-specific display mode.

Minimum Browser Install Signals

SignalWhy it matters
HTTPS or localhostMost PWA APIs require a secure context
Manifest linked from HTMLGives the browser app identity and presentation metadata
Name and short nameUsed in install UI and launch surfaces
IconsRequired for home screen, app launcher, task switcher, and splash surfaces
start_url and scopeDefine launch entry and app boundary
Installable display modestandalone, fullscreen, or minimal-ui gives app-like display

Chrome prompt behavior has stricter rules than manual menu installation. Older advice often says a service worker fetch handler is required for install. Current Chrome documentation says menu installation no longer universally requires that, while service workers remain essential for offline, reliability, push, and background behavior.

beforeinstallprompt

Use beforeinstallprompt as an optional enhancement, not the only install path.

type BeforeInstallPromptEvent = Event & {
  prompt: () => Promise<void>;
  userChoice: Promise<{ outcome: 'accepted' | 'dismissed' }>;
};

let deferredPrompt: BeforeInstallPromptEvent | undefined;

window.addEventListener('beforeinstallprompt', (event) => {
  event.preventDefault();
  deferredPrompt = event as BeforeInstallPromptEvent;
  document.querySelector('#install')?.removeAttribute('hidden');
});

document.querySelector('#install')?.addEventListener('click', async () => {
  if (!deferredPrompt) return;

  await deferredPrompt.prompt();
  const choice = await deferredPrompt.userChoice;
  console.log(choice.outcome);
  deferredPrompt = undefined;
});

Gotcha: Not every browser supports beforeinstallprompt. Always provide human instructions such as browser menu install or iOS Add to Home Screen when those targets matter.

Test Checklist

  • Manifest loads without DevTools errors.
  • Icons appear in install UI.
  • Installed window opens at the expected route.
  • App stays inside intended scope.
  • Offline reload works after first load if offline is promised.
  • Uninstall/reinstall does not create a second identity because id changed.