PWA analytics: the events that actually matter
A minimal analytics blueprint for Progressive Web Apps — install funnel, standalone sessions, push CTR, offline usage and the vanity metrics to skip.
Most PWAs are undermeasured. Teams see install counts and stop — missing the fact that installed users are the highest-LTV segment they have. Here’s the analytics blueprint we run on our own product and recommend to customers.
Install funnel (four events)
install_prompt_impression— popup shown.install_prompt_click— user tapped Install.install_prompt_outcome— accepted or dismissed (fromuserChoice).appinstalled— install completed (fromwindow.addEventListener('appinstalled')).
Display mode on every event
function displayMode() {
if (window.matchMedia('(display-mode: standalone)').matches) return 'standalone';
if (window.matchMedia('(display-mode: minimal-ui)').matches) return 'minimal-ui';
return 'browser';
}
analytics.track(event, { ...props, display_mode: displayMode() });
Report retention, revenue and session length split by display_mode. If you don’t, the installed-user premium disappears in the average.
Push funnel
push_permission_prompt.push_permission_outcome(granted / denied).push_delivered(fired inside the service workerpushhandler).push_click(fromnotificationclick).
Offline usage
Fire an offline_session_start when navigator.onLine flips false and the user keeps interacting. Buffer events to IndexedDB and flush on reconnect.
Vanity metrics to skip
- Raw install count without funnel context — says nothing about product-market fit.
- Notification opt-in rate on cold visitors — always terrible, never actionable.
- Lighthouse PWA score in production — a build-time signal, not a user one.
Tools that work
PostHog, Mixpanel, GA4, Amplitude all accept custom events. InstantPWA ships the install-funnel events out of the box — you attach your destination once and every widget reports.
Ship your install prompt in 60 seconds
InstantPWA is one line of code. Free forever for one widget, no card required.
Get started free