You launch a PWA, but the browser doesn't prompt installation? Check the console: likely a manifest error. Setting up the Web App Manifest seems like a small detail, but in 80% of cases it blocks the beforeinstallprompt event. We've seen projects where maskable icons were missing, display_override was incorrect, or iOS meta tags were forgotten. As a result, users don't get the icon on their home screen, and conversion drops by 30–40%. Let's break down how to make your app installable on Android, iOS, and desktop without unnecessary complexity.
Why Users Don't See the Install Button
Common reasons: missing manifest, invalid JSON, inappropriate icons (size or type), incorrect display (e.g., browser instead of standalone), no Service Worker, no HTTPS. But most often, icons don't meet requirements: Android needs maskable icons with purpose: maskable, iOS needs apple-touch-icon. Without them, the browser simply won't offer installation. We systematize the errors and provide ready solutions.
Full manifest.json
{
"name": "TechStore — Buy Electronics Online",
"short_name": "TechStore",
"description": "Smartphones, laptops, accessories. Fast delivery.",
"start_url": "/?utm_source=pwa&utm_medium=manifest",
"scope": "/",
"display": "standalone",
"display_override": ["window-controls-overlay", "standalone"],
"orientation": "any",
"theme_color": "#1a73e8",
"background_color": "#ffffff",
"lang": "en",
"dir": "ltr",
"categories": ["shopping", "lifestyle"],
"icons": [
{
"src": "/icons/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-192-maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/icons/icon-512-maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
],
"screenshots": [
{
"src": "/screenshots/catalog-mobile.webp",
"sizes": "390x844",
"type": "image/webp",
"form_factor": "narrow",
"label": "Product Catalog"
},
{
"src": "/screenshots/product-mobile.webp",
"sizes": "390x844",
"type": "image/webp",
"form_factor": "narrow",
"label": "Product Page"
},
{
"src": "/screenshots/catalog-desktop.webp",
"sizes": "1280x800",
"type": "image/webp",
"form_factor": "wide",
"label": "Catalog — Desktop"
}
],
"shortcuts": [
{
"name": "Cart",
"short_name": "Cart",
"url": "/cart?utm_source=pwa",
"icons": [{ "src": "/icons/cart-96.png", "sizes": "96x96", "type": "image/png" }]
},
{
"name": "Search",
"short_name": "Search",
"url": "/search?utm_source=pwa",
"icons": [{ "src": "/icons/search-96.png", "sizes": "96x96", "type": "image/png" }]
}
],
"protocol_handlers": [
{
"protocol": "web+techstore",
"url": "/products?q=%s"
}
]
}
Linking in HTML
<head>
<link rel="manifest" href="/manifest.json">
<!-- iOS — Safari does not read manifest for these parameters -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="TechStore">
<!-- iOS icons -->
<link rel="apple-touch-icon" href="/icons/apple-touch-icon-180.png">
<link rel="apple-touch-icon" sizes="152x152" href="/icons/apple-touch-icon-152.png">
<link rel="apple-touch-icon" sizes="120x120" href="/icons/apple-touch-icon-120.png">
<!-- iOS splash screens (optional) -->
<link rel="apple-touch-startup-image"
media="(device-width: 390px) and (device-height: 844px)"
href="/splashscreens/iphone12.png">
<!-- Windows tile -->
<meta name="msapplication-TileColor" content="#1a73e8">
<meta name="msapplication-TileImage" content="/icons/icon-144.png">
<meta name="theme-color" content="#1a73e8">
</head>
Comparison of Android and iOS Support
| Manifest field | Android (Chrome) | iOS (Safari) |
|---|---|---|
display |
Supported (standalone, fullscreen) | Ignored |
icons |
All sizes supported | Only apple-touch-icon |
shortcuts |
Supported | Not supported |
screenshots |
Supported (for installation) | Not supported |
scope |
Supported | Ignored |
Display Modes
| Value | Description |
|---|---|
browser |
Regular browser tab |
minimal-ui |
Minimal navigation elements |
standalone |
No address bar, like a native app |
fullscreen |
Full screen without browser UI |
display_override is an array with priority: the browser picks the first supported value. window-controls-overlay provides a custom title bar for Desktop PWA.
Maskable Icon
A maskable icon adapts to the device's shape (circle, square, squircle). Content must be within the safe zone — a central circle with 80% radius of the size. We use the sharp library to generate such icons with correct padding. Without maskable, the icon may be cropped on Android and Windows, ruining the user's perception at install time.
How to check a maskable icon
Upload the icon to maskable.app — it will show how it appears on different devices. If content extends beyond the safe zone, increase padding.Dynamic Manifest for Multilingual Sites
// routes/web.php
Route::get('/manifest.json', [ManifestController::class, 'index']);
// ManifestController.php
public function index(Request $request): JsonResponse
{
$locale = app()->getLocale();
$manifest = [
'name' => __('pwa.name'),
'short_name' => __('pwa.short_name'),
'description' => __('pwa.description'),
'start_url' => "/?lang={$locale}&utm_source=pwa",
'lang' => $locale,
'theme_color' => '#1a73e8',
'background_color' => '#ffffff',
'display' => 'standalone',
'scope' => '/',
'icons' => $this->getIcons(),
'shortcuts' => $this->getShortcuts($locale),
];
return response()->json($manifest)
->header('Content-Type', 'application/manifest+json');
}
Verification
- Chrome DevTools → Application → Manifest — check all fields, icons, and installability
- Lighthouse → PWA — verify all requirements
- PWABuilder — full audit and package generation for App Store
Use MDN documentation for spec reference.
According to the W3C specification, Web App Manifest is the standard for defining PWA appearance on devices.
Why Doesn't Manifest Work on iOS?
Safari ignores the display field and some others. The solution is to add the meta tags and apple-touch-icon as listed above. Without them, the PWA on iPhone opens in Safari, not as a standalone app. Also ensure start_url is correct and points to an HTTPS page.
How to Verify Manifest Correctness Before Deployment?
We use three tools: Chrome DevTools for quick checks, Lighthouse for a full PWA audit, and PWABuilder for final verification. PWABuilder also generates packages for Google Play and App Store if you need to publish the PWA in app stores. In our experience, around 80% of installation issues are resolved with a proper manifest.
What's Included
- Audit of current manifest (if existing)
- Generation of all icon sizes, including maskable (192, 512, 96, 144, 180)
- Configuration of
shortcutsandscreenshotsfor different devices - Markup of meta tags for iOS and Windows
- Verification via Lighthouse and PWABuilder
- Delivery of a ready manifest.json and update documentation
Our Process
- Requirements analysis (audience, devices, multilingual support)
- Manifest design (field set, icon structure)
- Implementation (icon generation, manifest writing, HTML integration)
- Testing on real devices (Android, iOS, Windows)
- Deployment and install monitoring
Estimated Timelines
Basic setup: from 4 to 8 hours. Complex projects with multilingual support and many icons: up to 2 business days. Cost is determined individually — depends on number of localizations and CMS integration needs. Order a PWA manifest setup from us — get a ready JSON and icons in 4 hours. Contact us to discuss your project and get a preliminary estimate — we'll explain how to optimize installation and boost conversion.
Our engineers have 5+ years of experience in PWA, web performance certifications, and over 50 projects completed.







