PWA Essentials: Web App Manifest Configuration Guide and Generator Implementation
PWA Essentials: Web App Manifest Configuration Guide and Generator Implementation#
Recently converted a web app to PWA for app store submission. Web App Manifest seemed simple at first, but the details caught me off guard. Built a generator tool and documented the key configuration points.
What is Manifest and Why PWA Needs It?#
Simply put, manifest.json is the “ID card” for your PWA. The browser uses it to know:
- What’s the app name
- What’s the launch icon
- Should it run fullscreen or in browser mode
- Theme color and background color
Without manifest, your web app is just a regular webpage. No “Add to Home Screen”, no offline support, no app store submission.
A minimal manifest:
{
"name": "My PWA App",
"short_name": "PWA",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#000000",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
Four Display Modes Explained#
The display field determines how your app appears. This is where most developers stumble:
1. standalone (Recommended)#
"display": "standalone"
Most native-like mode. Hides browser address bar and tabs, showing only app content. Users feel like using a standalone app.
Best for: Tools, games, content apps
2. fullscreen#
"display": "fullscreen"
Complete fullscreen, even hides status bar. For immersive experiences.
Best for: Games, video players, presentation tools
Note: iOS Safari doesn’t support fullscreen, falls back to standalone
3. minimal-ui#
"display": "minimal-ui"
Keeps minimal browser controls (back button). Between standalone and browser.
Best for: Apps where users should know it’s a webpage
4. browser#
"display": "browser"
Standard browser mode with all controls. Basically a regular webpage.
Best for: Content sites, blogs
Icons Configuration Pitfalls#
Icon configuration is the most error-prone part. Docs say provide multiple sizes, but which ones?
Required Sizes#
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
192x192 is Android’s minimum requirement. 512x512 is for splash screens.
Recommended Additional Sizes#
"icons": [
{ "src": "/icon-72.png", "sizes": "72x72", "type": "image/png" },
{ "src": "/icon-96.png", "sizes": "96x96", "type": "image/png" },
{ "src": "/icon-128.png", "sizes": "128x128", "type": "image/png" },
{ "src": "/icon-144.png", "sizes": "144x144", "type": "image/png" },
{ "src": "/icon-152.png", "sizes": "152x152", "type": "image/png" },
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-384.png", "sizes": "384x384", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
Maskable Icons (Android Adaptive Icons)#
Android 8.0+ supports adaptive icons, requiring separate configuration:
{
"src": "/icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
}
Key point: Maskable icons need 20% safe zone padding because the system clips them into circles, rounded rectangles, etc.
Purpose Field Values#
"purpose": "any" // Default, standard icon
"purpose": "maskable" // Adaptive icon
"purpose": "any maskable" // Supports both
Shortcuts: Long-press Quick Actions#
Similar to native app 3D Touch shortcuts:
"shortcuts": [
{
"name": "New Task",
"short_name": "New",
"description": "Quickly create a new task",
"url": "/tasks/new",
"icons": [{ "src": "/icons/new-task.png", "sizes": "96x96" }]
},
{
"name": "Search",
"short_name": "Search",
"url": "/search"
}
]
Limit: Maximum 4 shortcuts. Android and Windows support it, iOS doesn’t.
Categories and Screenshots: App Store Optimization#
Important when submitting to Google Play or Microsoft Store:
{
"categories": ["productivity", "utilities"],
"screenshots": [
{
"src": "/screenshots/home.png",
"sizes": "1080x1920",
"type": "image/png",
"label": "Home Screen"
},
{
"src": "/screenshots/settings.png",
"sizes": "1080x1920",
"type": "image/png",
"label": "Settings Page"
}
]
}
Categories options: games, social, entertainment, productivity, utilities, etc.
Implementation: Building the Generator#
Built an online tool for easy configuration: Manifest Generator
Core implementation is straightforward - a form + JSON serialization:
interface ManifestData {
name: string
short_name: string
description: string
start_url: string
display: string
orientation: string
theme_color: string
background_color: string
icons: IconEntry[]
}
const manifestJSON = JSON.stringify(manifest, null, 2)
But several details matter:
1. Template System#
Different frameworks have slightly different PWA configurations:
const templates = {
basic: { /* Basic config */ },
nextjs: { /* Next.js specific */ },
react: { /* CRA specific */ }
}
Next.js typically uses /icons/icon-192x192.png, while CRA uses /logo192.png.
2. Dynamic Icon Array Management#
const addIcon = () => {
setManifest(prev => ({
...prev,
icons: [...prev.icons, { src: '', sizes: '', type: 'image/png' }]
}))
}
const removeIcon = (index: number) => {
setManifest(prev => ({
...prev,
icons: prev.icons.filter((_, i) => i !== index)
}))
}
3. Filter Empty Icons#
When generating JSON, filter out unfilled icons:
const filteredIcons = icons.filter(icon => icon.src || icon.sizes)
4. Color Picker Sync#
Color input supports two methods: color picker + text input, need to keep them in sync:
<input type="color" value={manifest.theme_color} onChange={e => updateField('theme_color', e.target.value)} />
<input type="text" value={manifest.theme_color} onChange={e => updateField('theme_color', e.target.value)} />
Common Issues Troubleshooting#
1. “Add to Home Screen” Not Showing#
Checklist:
- Is manifest.json linked via
<link rel="manifest"> - Is it running on HTTPS (localhost exempted)
- Do icons meet 192x192 and 512x512 requirements
- Is Service Worker registered
2. iOS Icons Not Working#
iOS doesn’t fully support manifest. Need extra meta tags:
<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="/apple-touch-icon.png">
3. Theme Color Not Applying#
theme_color affects browser address bar color, but only works in Android Chrome. iOS Safari needs apple-mobile-web-app-status-bar-style.
4. White Splash Screen#
Check if background_color matches your actual page background. Splash screen shows background_color + name + icon.
Testing Tools#
- Chrome DevTools: Application panel → Manifest
- Lighthouse: Audit PWA compliance
- Manifest Validator: https://manifest-validator.appspot.com/
Summary#
Web App Manifest is foundational for PWA, but has many details. Recommend using a generator tool for quick setup, then fine-tune based on actual needs.
Key configuration points:
display:standaloneis most universal- Icons: at minimum provide 192x192 and 512x512
- iOS: requires extra meta tags
theme_colorandbackground_color: should match your design
Related: PWA Icon Generator | Service Worker Generator