🚀AdvancedProgressive Web Apps

Web App Manifest

Create a Web App Manifest to make your site installable as a PWA with a custom name, icon, colors, and display mode.

Overview

A Web App Manifest is a JSON file that describes your web application to the browser, enabling it to be installed on a device's home screen or desktop like a native app. This is the cornerstone of Progressive Web App (PWA) installability. The manifest is linked from the HTML document with `<link rel="manifest" href="/manifest.json">`. It defines the app's name, icons (for various sizes and contexts), theme color, background color, start URL, display mode, and much more. When the browser detects a manifest alongside a Service Worker, it shows an install prompt to the user. Installation provides a standalone window (no browser chrome), fast launch from the OS, and the ability to appear in the OS app switcher, dock, or taskbar bridging the gap between web and native app experiences.

Key Points

  • •`name` and `short_name` full app name and abbreviated version for limited space contexts
  • •`icons` array provide sizes: 192×192 and 512×512 minimum; add maskable icons for adaptive icon shapes
  • •`start_url` the URL the app opens to when launched from the home screen
  • •`display` "standalone" removes browser chrome; "fullscreen" hides OS bars; "minimal-ui" shows back/reload
  • •`theme_color` colors the browser toolbar and OS taskbar; `background_color` shows while app loads
  • •`scope` limits which URLs are part of the app (navigating outside opens the system browser)
  • •Manifest + HTTPS + Service Worker = full PWA install prompt eligibility in Chrome/Edge

Examples

Complete manifest.json for a PWA

{
  "name": "Task Manager Pro",
  "short_name": "Tasks",
  "description": "Manage your daily tasks efficiently",
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "orientation": "portrait-primary",
  "theme_color": "#3b82f6",
  "background_color": "#ffffff",
  "lang": "en",
  "dir": "ltr",
  "categories": ["productivity", "utilities"],
  "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.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "screenshots": [
    {
      "src": "/screenshots/desktop.png",
      "sizes": "1280x720",
      "type": "image/png",
      "form_factor": "wide",
      "label": "Desktop view"
    }
  ]
}

Maskable icons fill the entire safe zone use maskable.app to design icons that look good in any shape.

Linking the manifest and setting theme color in HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Link the manifest -->
    <link rel="manifest" href="/manifest.json">

    <!-- Theme color for address bar (also in manifest, but this is picked up faster) -->
    <meta name="theme-color" content="#3b82f6">

    <!-- iOS-specific (Safari does not use the manifest fully) -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">
    <meta name="apple-mobile-web-app-title" content="Tasks">
    <link rel="apple-touch-icon" href="/icons/icon-180.png">

    <title>Task Manager Pro</title>
  </head>
  <body>...</body>
</html>

Safari (iOS) has partial PWA support use apple-mobile-web-app-* meta tags alongside the manifest.

Listening to beforeinstallprompt to control the install UI

<button id="install-btn" style="display:none">
  Install App
</button>

<script>
let deferredPrompt;

window.addEventListener('beforeinstallprompt', (event) => {
  event.preventDefault();
  deferredPrompt = event;
  document.getElementById('install-btn').style.display = 'block';
});

document.getElementById('install-btn').addEventListener('click', async () => {
  if (!deferredPrompt) return;
  deferredPrompt.prompt();
  const { outcome } = await deferredPrompt.userChoice;
  console.log('User response:', outcome);
  deferredPrompt = null;
  document.getElementById('install-btn').style.display = 'none';
});

window.addEventListener('appinstalled', () => {
  console.log('App was installed!');
});
</script>

beforeinstallprompt only fires when the PWA meets all installability criteria.

Common Mistakes

  • Providing only one icon size you need at least 192×192 and 512×512; missing sizes cause install prompt failures in Chrome
  • Using a relative start_url without a leading slash "/tasks" is correct; "tasks" may break depending on the served path
  • Forgetting iOS-specific meta tags Safari ignores the Web App Manifest for most properties; use apple-mobile-web-app-* tags for iOS support

Note

Use Chrome DevTools > Application > Manifest to validate your manifest and see which installability criteria are met or missing.

Exercises

Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

What is the minimum set of things required for a site to show an install prompt in Chrome?