Icons for Progressive Web Apps
Progressive Web Apps require careful icon configuration to provide native-like experiences across platforms. Beyond regular web icons, PWAs need app icons for installation, splash screens, and offline scenarios.
PWA App Icon Requirements
The web app manifest defines app icons shown on home screens and app launchers:
// manifest.json
{
"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"
},
{
"src": "/icons/icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}Understanding Icon Sizes
Different platforms use different icon sizes:
- 192×192 - Minimum required, Android home screen
- 512×512 - Required for PWA install prompt, splash screen
- 384×384 - Android splash screen (recommended)
- 180×180 - iOS (via apple-touch-icon, not manifest)
- 152×152, 167×167 - iPad variants
Include at minimum 192px and 512px. Add intermediate sizes for better quality scaling.
Maskable Icons
Android adaptive icons use masks that vary by device. Maskable icons accommodate this:
- Place important content in the center 80% (safe zone)
- Background extends to fill the entire canvas
- Different devices apply circular, rounded square, or other masks
The "purpose": "maskable" property tells the browser this icon is designed for masking.
// Provide both regular and maskable
{
"src": "/icons/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any" // regular icon
},
{
"src": "/icons/icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}iOS PWA Icons
iOS doesn't fully support the manifest icons property. Use HTML link tags:
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="152x152" href="/icons/icon-152.png"> <link rel="apple-touch-icon" sizes="167x167" href="/icons/icon-167.png"> <link rel="apple-touch-icon" sizes="180x180" href="/icons/icon-180.png">
Splash Screen Configuration
iOS requires explicit splash screen definitions:
<link rel="apple-touch-startup-image"
href="/splash/splash-640x1136.png"
media="(device-width: 320px) and (device-height: 568px)">
<link rel="apple-touch-startup-image"
href="/splash/splash-750x1334.png"
media="(device-width: 375px) and (device-height: 667px)">Android creates splash screens automatically from the manifest icon and theme color.
Service Worker Icon Caching
Cache icons for offline availability:
// In service worker
const CACHE_NAME = 'app-icons-v1';
const ICON_URLS = [
'/icons/icon-192.png',
'/icons/icon-512.png',
'/icons/favicon.ico',
// ... other critical icons
];
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(ICON_URLS);
})
);
});UI Icon Caching Strategy
For in-app UI icons, use a cache-first strategy:
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/icons/')) {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request).then((networkResponse) => {
// Cache new icons
const responseClone = networkResponse.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, responseClone);
});
return networkResponse;
});
})
);
}
});Icon Preloading
Preload critical icons to prevent FOIT (Flash of Invisible Icons):
<link rel="preload" href="/icons/sprite.svg" as="image"> <link rel="preload" href="/icons/logo.svg" as="image">
Shortcuts (App Shortcuts)
PWAs can define shortcuts that appear in context menus:
// manifest.json
{
"shortcuts": [
{
"name": "New Document",
"url": "/new",
"icons": [
{
"src": "/icons/shortcut-new-96.png",
"sizes": "96x96"
}
]
},
{
"name": "Recent",
"url": "/recent",
"icons": [
{
"src": "/icons/shortcut-recent-96.png",
"sizes": "96x96"
}
]
}
]
}Theme Color and Icons
Theme color affects how icons appear in context:
// manifest.json
{
"theme_color": "#4a90d9",
"background_color": "#ffffff"
}Choose colors that complement your app icon for a cohesive installed experience.
Testing PWA Icons
Verify icons work correctly:
- Chrome DevTools - Application tab shows manifest and icons
- Lighthouse - Audits PWA icon requirements
- Maskable.app - Test maskable icon safe zones
- Real device testing - Install on actual phones
Icon Generation Tools
Generate all required sizes from a source image:
- PWA Asset Generator - CLI tool for all platform icons
- Real Favicon Generator - Web-based, comprehensive output
- Maskable.app Editor - Create and preview maskable icons
Start with a high-resolution source (1024×1024 minimum) for best scaling results.
Offline Icon Fallbacks
Handle icons gracefully when offline:
// Provide inline SVG fallback
const Icon = ({ src, fallback }) => {
const [error, setError] = useState(false);
if (error) return fallback;
return <img src={src} onError={() => setError(true)} />;
};