The single most common mistake is treating a favicon as a design task. It is a manifest task: the images already exist in your brand kit, and the work is declaring them in the right places with the right sizes.
Step 1 — Start with an SVG
Modern browsers prefer a vector icon because it renders crisply at 16, 32 and 64 pixels from one file and can adapt to dark mode through a media query inside the SVG itself.
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> Keep the artwork inside a 32 × 32 viewBox with a couple of pixels of padding. Logotypes with fine strokes disappear at tab size — this is the moment to simplify, not later.
Step 2 — Add the raster fallbacks
Some browsers, feed readers and corporate proxies still ignore SVG icons. A 32 × 32 PNG covers them, and a 16 × 16 keeps the tab sharp on non-retina displays.
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="icon" href="/favicon.ico" sizes="32x32" /> Step 3 — Cover iOS
When someone adds your site to an iPhone home screen, iOS looks for an apple-touch-icon at 180 × 180. If it is absent you get a screenshot of the page instead.
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> - Export exactly 180 × 180 — iOS scales anything else and the corners look soft.
- Never leave transparency. iOS does not fill it, so the icon sits on a black or white hole depending on the OS version.
- Add rounded corners yourself only if you want them; iOS applies its own mask to the square file.
Step 4 — Publish the Web App Manifest
Android ignores apple-touch-icon entirely. It reads the manifest, so the manifest must declare a 192 × 192 icon for the launcher and a 512 × 512 for splash screens and install prompts.
{
"name": "Example",
"short_name": "Example",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icon-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
} Then reference it from every page:
<link rel="manifest" href="/site.webmanifest" /> Step 5 — Finish with the two small touches
Neither is required, and both are the difference between a site that looks finished and one that looks assembled.
- mask-icon — a single-colour SVG plus a colour value, used by Safari pinned tabs.
- theme-color — tints the mobile address bar and the Android task switcher.
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#d97706" />
<meta name="theme-color" content="#d97706" /> Step 6 — Verify, then verify again after deploy
- 01 Run the URL through the favicon checker and confirm all 14 checks pass.
- 02 Open the site in a private window — favicons are cached harder than most assets.
- 03 Check /favicon.ico directly; a 404 there is invisible in the browser but breaks feeds and crawlers.
- 04 Add the manifest icon check to CI so a redesign cannot silently drop a size.
One SVG, two PNGs, one Apple touch icon, one manifest. Five files, seven platforms.