Web Export Bundle

Favicon and PWA assets for a modern website, with optional legacy fallbacks.

Modern-first bundle: covers current browsers, PWAs, and the iOS Add-to-Home-Screen surface out of the box. Legacy fallbacks are opt-in.

Default set

your-app/public/
├── favicon.ico              # 16, 32, 48 — legacy + implicit /favicon.ico probe
├── icon.svg                 # vector — modern tabs, hi-DPI
├── icon-192.png             # PWA install icon
├── icon-512.png             # large PWA icon / splash
├── icon-512-maskable.png    # Android adaptive (full-bleed, safe-zone padded)
├── apple-touch-icon.png     # 180 — iOS Add to Home Screen
├── manifest.webmanifest
└── SETUP.md

Paste this into <head>

<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" type="image/svg+xml" href="/icon.svg">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.webmanifest">
<meta name="theme-color" content="#ffffff">

Order matters: browsers pick the last matching rel="icon" they support, so SVG comes after ICO.

For per-scheme browser chrome colors, split theme-color:

<meta name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff">
<meta name="theme-color" media="(prefers-color-scheme: dark)"  content="#000000">

Next.js (App Router)

// app/layout.tsx
export const metadata = {
  icons: {
    icon: [
      { url: '/favicon.ico', sizes: 'any' },
      { url: '/icon.svg', type: 'image/svg+xml' },
    ],
    apple: '/apple-touch-icon.png',
  },
  manifest: '/manifest.webmanifest',
};

manifest.webmanifest

The shipped manifest is a stub — edit name, short_name, and theme_color to match the app:

{
  "name": "Your App Name",
  "short_name": "App",
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
    {
      "src": "/icon-512-maskable.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable"
    }
  ],
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display": "standalone"
}

Maskable icon

icon-512-maskable.png is generated from your design with three forced adjustments so it survives Android's adaptive-icon mask:

  • Padding is zeroed (background fills edge to edge).
  • Artwork is scaled to fit the inner 80% safe zone (W3C requirement).
  • Border radius is removed (the OS supplies the clip shape).

The source design is untouched; these only apply at export time.

Legacy fallbacks (opt-in)

Toggle this on if the project still needs IE / old Edge pinned-tile support or explicit small PNG fallbacks. Adds:

FileWhen
icon-16.png, icon-32.pngBrowsers that ignore ICO
mstile-150x150.png + browserconfig.xmlLegacy Windows pinned tiles

For most new projects, skip this — favicon.ico already handles legacy browsers that probe for it.

Compatibility map

SurfaceAsset
Modern browser tabicon.svg
Legacy browser tabfavicon.ico
iOS Add to Home Screenapple-touch-icon.png
PWA install promptmanifest.webmanifest + icon-192.png, icon-512.png
Android adaptive iconicon-512-maskable.png
Legacy Windows pinned sitesbrowserconfig.xml, mstile-150x150.png (opt-in)

Icon not updating, PWA icon missing, manifest errors — see Troubleshooting.