Android PWA Add to Home Screen: Complete Setup Guide for 2026

You spend weeks building a polished Progressive Web App, drive traffic through Meta ads and organic search, and watch users land on your site — only to leave and never return. Sound familiar? The problem is not your app; it is the gap between a browser tab and a permanent place on the home screen. Research consistently shows that users who install a PWA via Add to Home Screen (A2HS) return 3x more often and convert at significantly higher rates than casual visitors. In 2026, with Chrome and Samsung Internet offering even smoother install flows, there has never been a better time to implement a bulletproof A2HS strategy for your Android PWA.

In this guide, you will learn exactly how to configure your web app manifest, register a service worker, intercept the beforeinstallprompt event, and design a custom install banner that maximizes conversion — all with production-ready code examples you can copy today.

Want to boost post-click conversions? Talk to DeepClick

What Is “Add to Home Screen” for Android PWA

Add to Home Screen is a browser-native feature that lets users install a Progressive Web App directly onto their Android device’s home screen — without visiting the Google Play Store. Once installed, the PWA launches in a standalone window (no browser chrome), receives push notifications, and behaves almost identically to a native Android application.

On Android, Chrome triggers an automatic “mini-infobar” install prompt when it detects that a site meets specific installability criteria. However, relying solely on this default prompt leaves conversion on the table. By intercepting the underlying beforeinstallprompt event, you can present a custom, well-timed install experience that converts up to 5–6x better than the default mini-infobar.

If you are already using PWA push notifications on Android, adding A2HS is the natural next step — installed users are far more likely to opt in to notifications and engage long-term.

Prerequisites — What Your PWA Needs Before A2HS Works

Before Chrome will fire the beforeinstallprompt event, your site must pass several checks. Missing even one requirement means the install prompt never appears, and you will not see any errors in the UI — only in DevTools. Let us walk through each prerequisite.

Valid Web App Manifest

Your site must serve a Web App Manifest (manifest.json or manifest.webmanifest) linked in the <head> of every page. The manifest must include, at minimum:

  • name or short_name
  • start_url
  • display set to standalone, fullscreen, or minimal-ui
  • At least one icon in the icons array that is 192×192 px and another that is 512×512 px
  • prefer_related_applications must not be true

Service Worker with Fetch Handler

Chrome requires an active service worker with a registered fetch event handler. The service worker does not need to cache everything offline — it simply needs to intercept fetch requests. Even a minimal pass-through service worker satisfies this requirement, although you should implement real caching for production.

HTTPS and Installability Criteria

Your site must be served over HTTPS (or localhost for development). As of 2026, Chrome also checks that the page has not been previously dismissed by the user within a cooldown period. Additionally, the user must have engaged with the domain for a minimum threshold — typically interacting with the page for at least 30 seconds — before the browser considers showing the prompt.

Step-by-Step Implementation Guide

Now let us build the entire A2HS flow from scratch. Each step includes production-ready code you can adapt for your project.

Step 1 — Configure Your manifest.json Correctly

Create a manifest.json file in your project root and link it from every HTML page:

{
  "name": "My Awesome PWA",
  "short_name": "AwesomePWA",
  "description": "A blazing-fast progressive web app",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#6200ee",
  "orientation": "portrait-primary",
  "icons": [
    {
      "src": "/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    }
  ],
  "prefer_related_applications": false
}

Then add the link tag in your HTML <head>:

<link rel="manifest" href="/manifest.json">

Pro tip: Use "purpose": "any maskable" on your 512px icon so Android adaptive icon shapes look great. Test your icons with the Maskable.app tool before deploying.

Step 2 — Register a Service Worker

Register the service worker from your main JavaScript file. The service worker itself needs a fetch handler — here is a minimal version with a cache-first strategy for static assets:

// main.js — register the service worker
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/sw.js')
      .then(reg => console.log('SW registered, scope:', reg.scope))
      .catch(err => console.error('SW registration failed:', err));
  });
}
// sw.js — service worker with fetch handler
const CACHE_NAME = 'pwa-cache-v1';
const PRECACHE_URLS = ['/', '/index.html', '/styles.css', '/main.js'];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(PRECACHE_URLS))
  );
  self.skipWaiting();
});

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(keys =>
      Promise.all(
        keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))
      )
    )
  );
  self.clients.claim();
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cached => cached || fetch(event.request))
  );
});

This cache-first approach is great for static assets. For API calls, consider a network-first or stale-while-revalidate strategy. If you need help with optimizing page speed for better conversions, caching is one of the most impactful levers you can pull.

Step 3 — Handle the beforeinstallprompt Event

This is the core of your custom A2HS flow. Chrome fires beforeinstallprompt when all installability criteria are met. You must capture the event, prevent the default mini-infobar, and store the event for later use:

Step-by-step PWA installation flow on Android from browser to home screen
let deferredPrompt = null;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent the default mini-infobar from appearing
  e.preventDefault();

  // Stash the event so it can be triggered later
  deferredPrompt = e;

  // Show your custom install UI
  showInstallBanner();

  console.log('beforeinstallprompt fired and captured');
});

window.addEventListener('appinstalled', () => {
  // Clear the deferred prompt
  deferredPrompt = null;

  // Hide the install banner
  hideInstallBanner();

  // Log the install for analytics
  console.log('PWA was installed');
  trackEvent('pwa_installed');
});

The appinstalled event fires after a successful installation, giving you the perfect hook to update your UI and track the conversion in your analytics platform.

Step 4 — Design a Custom Install Banner

Now wire up a visible, compelling install button that triggers the captured prompt:

function showInstallBanner() {
  const banner = document.getElementById('install-banner');
  banner.classList.add('visible');
}

function hideInstallBanner() {
  const banner = document.getElementById('install-banner');
  banner.classList.remove('visible');
}

document.getElementById('install-btn').addEventListener('click', async () => {
  if (!deferredPrompt) return;

  // Show the browser's install prompt
  deferredPrompt.prompt();

  // Wait for the user's response
  const { outcome } = await deferredPrompt.userChoice;

  console.log(`User response: ${outcome}`);

  if (outcome === 'accepted') {
    trackEvent('pwa_install_accepted');
  } else {
    trackEvent('pwa_install_dismissed');
  }

  // Clear the deferred prompt — it can only be used once
  deferredPrompt = null;
  hideInstallBanner();
});

For the HTML, create a banner that clearly communicates the value of installing:

<div id="install-banner" class="install-banner">
  <p><strong>Get the full app experience</strong> — faster loading, offline access, and push notifications.</p>
  <button id="install-btn">Install App</button>
  <button id="install-dismiss">Not now</button>
</div>

Step 5 — Track Install Success with Analytics

You cannot improve what you do not measure. Send install events to Google Analytics 4 (or your preferred platform) to understand conversion rates:

function trackEvent(eventName, params = {}) {
  // Google Analytics 4
  if (typeof gtag === 'function') {
    gtag('event', eventName, {
      event_category: 'PWA',
      ...params,
    });
  }

  // Also send to your own endpoint for server-side tracking
  navigator.sendBeacon('/api/analytics', JSON.stringify({
    event: eventName,
    timestamp: Date.now(),
    ...params,
  }));
}

Track these key events: pwa_install_prompt_shown, pwa_install_accepted, pwa_install_dismissed, and pwa_installed. This gives you a full funnel to optimize.

Best Practices to Maximize Install Rates

Getting the technical implementation right is only half the battle. The other half is convincing users that installing your PWA is worth their time. Here are proven strategies for 2026.

Timing the Prompt Right

The biggest mistake developers make is showing the install prompt immediately on page load. Users who have not yet experienced your app’s value have no reason to install it. Instead, defer the prompt until after a meaningful interaction:

  • After completing an action: Show the prompt after the user completes a search, reads an article, or adds an item to their cart.
  • After multiple visits: Use localStorage to count visits and only show the banner on the second or third session.
  • After time on page: Wait at least 30–60 seconds of active engagement before displaying.
  • After scroll depth: Trigger at 50% or 75% scroll depth, indicating genuine interest.

This approach is similar to the progressive disclosure strategy used in high-converting landing pages — reveal the ask only after delivering value.

Showing Value Before Asking

Your install banner copy should answer the user’s implicit question: “What do I get?” Rather than a generic “Install our app,” emphasize concrete benefits:

  • “Get instant loading — even offline”
  • “Never miss a deal — enable push notifications
  • “Access your dashboard right from your home screen

When possible, personalize the message. If the user has items in their cart, say “Install to save your cart and check out faster.” Context-aware messaging dramatically improves acceptance rates.

A/B Testing Install Banners

Treat your install prompt like any other conversion element — test it rigorously. Variables worth testing include:

  • Banner position: Bottom sheet vs. top bar vs. inline card
  • Copy: Feature-focused vs. emotion-focused vs. urgency-focused
  • Timing: Immediate vs. delayed vs. exit-intent
  • Design: Minimal text link vs. full-width banner with icon

Use your analytics events (from Step 5) to calculate the prompt-shown-to-install-accepted conversion rate for each variant. Even small improvements here compound over thousands of visitors. For advertisers running Meta campaigns, optimizing install rates is just as important as exiting the learning phase — both directly impact your cost per acquisition.

Troubleshooting Common A2HS Issues on Android

If your beforeinstallprompt event is not firing, work through this checklist systematically:

  • Manifest not linked: Open Chrome DevTools → Application → Manifest. If it shows “No manifest detected,” check your <link rel="manifest"> tag.
  • Manifest errors: The Manifest panel in DevTools highlights missing or invalid fields. Common issues include missing start_url, icons that are too small, or display set to browser.
  • No service worker: Go to Application → Service Workers. If no worker is registered or it is not active, the prompt will not fire. Check for registration errors in the Console.
  • Service worker missing fetch handler: Even if the SW is registered, Chrome requires a fetch event listener. A SW that only handles push or sync will not qualify.
  • HTTPS not configured: On non-localhost origins, HTTPS is mandatory. Mixed content warnings can also block installation.
  • User already installed: If the PWA is already installed, Chrome will not fire beforeinstallprompt. Use window.matchMedia('(display-mode: standalone)').matches to detect if the app is running in standalone mode.
  • Incognito mode: A2HS does not work in Chrome incognito windows.
  • Recently dismissed: If the user dismissed the prompt, Chrome enforces a cooldown (currently around 2 weeks). You cannot force the prompt to reappear.

For a quick diagnostic, open Chrome DevTools, navigate to the Application tab, and look at the Manifest section. Chrome now displays a clear “Installability” status with specific error messages when criteria are not met.

Additionally, you can audit your PWA using Lighthouse. Run a Lighthouse audit in Chrome DevTools or via the command line, and check the “PWA” category. It will flag any installability issues and provide actionable recommendations.

If you are combining A2HS with push notifications, make sure to review the complete PWA push notification setup guide to ensure both features work together seamlessly.


Stop losing conversions after the click.

DeepClick helps Meta advertisers fix post-click drop-offs and improve CVR by 30%+ through automated re-engagement and post-click link optimization.

Book a Free Demo


Posted

in

by

Tags:

Comments

留下评论