Making Your Flutter Web App a PWA
Why PWA Matters for Flutter Web
A properly configured PWA gives Flutter Web apps:
- Home screen install (with real app icon)
- Offline capability via Service Worker cache
- Install promotion banner in-app
- Standalone display on iOS Safari (no browser chrome)
1. Configure manifest.json
{
"name": "My App",
"short_name": "My App",
"description": "Your app description",
"start_url": ".",
"display": "standalone",
"background_color": "#0A0A0A",
"theme_color": "#FF6B00",
"orientation": "portrait-primary",
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
}
]
}
Without "purpose": "maskable", Android will render your icon as a tiny image in a white circle.
2. iOS-Specific Meta Tags in index.html
iOS Safari ignores manifest.json entirely. Add these to web/index.html:
<head>
<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#FF6B00">
<!-- iOS PWA config -->
<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="My App">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
</head>
Skip these and your app won't behave as a standalone app on iPhone.
3. Service Worker — Flutter Handles It
Flutter Web auto-generates flutter_service_worker.js at build time. The default index.html already registers it:
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/flutter_service_worker.js');
});
}
</script>
No extra configuration needed. The service worker handles asset caching automatically.
4. In-App Install Banner
class PwaInstallBanner extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).colorScheme.surface,
padding: const EdgeInsets.all(16),
child: Row(
children: [
const Icon(Icons.install_mobile),
const SizedBox(width: 12),
const Expanded(
child: Text('Add to home screen for offline access'),
),
TextButton(
onPressed: _triggerNativeInstallPrompt,
child: const Text('Install'),
),
],
),
);
}
void _triggerNativeInstallPrompt() {
// Use dart:js_interop to call the beforeinstallprompt event
}
}
Show this banner after a few sessions to avoid being intrusive on first visit.
5. Lighthouse PWA Checklist
Run Chrome DevTools → Lighthouse → PWA to audit:
| Requirement | Solution |
|---|---|
| Web app manifest | manifest.json + <link rel="manifest">
|
| Service Worker | Flutter auto-generates |
| HTTPS | Firebase Hosting (default) |
| Icons (192 + 512) | Add both to manifest icons array |
| Maskable icon | Add "purpose": "maskable" variant |
| Offline behavior | Service Worker cache |
Firebase Hosting automatically provides HTTPS, which is required for PWA.
Result
After these changes, users on Android Chrome will see a "Add to Home Screen" banner. iOS users can use the Share menu → "Add to Home Screen".
The app icon appears on the home screen, launches full-screen, and works offline for cached assets — all without an App Store submission.
Building in public: https://my-web-app-b67f4.web.app/
Flutter #PWA #buildinpublic #webdev #mobile
United States
NORTH AMERICA
Related News
What Does "Building in Public" Actually Mean in 2026?
20h ago
The Agentic Headless Backend: What Vibe Coders Still Need After the UI Is Done
20h ago
Why I’m Still Learning to Code Even With AI
22h ago
Students Boo Commencement Speaker After She Calls AI the 'Next Industrial Revolution'
5h ago

Testing for ‘Bad Cholesterol’ Doesn’t Tell the Whole Story
5h ago