Topic 6.4
Favicons and the Web App Manifest
In one line
A small set of icon links (an ICO, an SVG and a 180px Apple icon), a theme-color meta tag and a manifest.webmanifest file give your site its icon on tabs, bookmarks and home screens, and let it be installed like an app.
Think of it like this
A shop's sign and its uniform. The tiny logo on the door (the favicon) helps you find the shop in a busy street of tabs. The bigger sign over the entrance (the home-screen icon) is what you see when the shop is on your phone. The staff uniform colour (the theme colour) makes everything around the shop match. The manifest is the shop's registration form: name, opening page, colours and every size of its logo.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Favicon
- The small icon on a browser tab and in bookmarks.
- ICO
- An old icon file format that can hold several sizes in one file. Browsers look for
/favicon.icoby default. - SVG
- An image format made of shapes instead of pixels, so it stays sharp at any size.
- apple-touch-icon
- The icon iPhones and iPads use when a site is added to the home screen.
- theme-color
- A meta tag suggesting a colour for the browser's bars around your page.
- JSON
- A text format for data: names in quotes, a colon, then a value, inside curly braces.
- Web app manifest
- A JSON file describing the site as an app: name, start page, colours and icons.
- PWA
- Progressive Web App: a website that can be installed and opened like an app.
- Maskable icon
- An icon with extra padding so it still looks right when the phone crops it into a circle or other shape.
Step by step
01The classic fallback
Put a favicon.ico (with 32 and 16 px inside) at the root of the site and link it. Older browsers, RSS readers and some tools only look for this.
<link rel="icon" href="/favicon.ico" sizes="32x32">02A sharp SVG for modern browsers
The SVG icon can adapt to dark mode by itself. Browsers that support SVG favicons prefer it.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
circle { fill: #0f766e; }
@media (prefers-color-scheme: dark) { circle { fill: #5eead4; } }
</style>
<circle cx="16" cy="16" r="14"/>
</svg>03Apple and theme colour
One 180 × 180 PNG for iOS. Two theme colours, one per colour scheme.
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<meta name="theme-color" content="#0f766e" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#042f2e" media="(prefers-color-scheme: dark)">04Write the manifest
Save it as manifest.webmanifest and serve it with the type application/manifest+json. JSON is strict: double quotes only, and no comma after the last item.
{
"name": "Asha's Kitchen",
"short_name": "Kitchen",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0f766e",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}05Link it and check it
Add the manifest link, then open DevTools → Application → Manifest. It lists every field, shows each icon, and reports problems such as a missing 512 px icon.
<link rel="manifest" href="/manifest.webmanifest">Try it yourself
- 1
Add a maskable icon
In the manifest checker, add a third icon with
"purpose": "maskable". Predict the last console line, then run. Remember the comma between array items. - 2
Break the JSON on purpose
Add a comma after the last icon (
}→},). Predict what happens, run it, and read the error in the console. JSON doesn't allow trailing commas, unlike JavaScript. - 3
Recolour the icon
In the first example, change
fill='teal'tofill='crimson'in the three<img>sources. The vector stays sharp at every size. Then open DevTools → Application → Manifest on any big web app and look at its icon list.
Code & diagrams
The preview runs inside this page, so you won't see its icon on your tab; on a real site you would. `link.sizes` is a list, so `.value` gives its text.
Preview
Console
Nothing logged yet.Expected console output
icon 32x32 /favicon.ico
icon image/svg+xml (inline SVG)
apple-touch-icon /apple-touch-icon.png
manifest /manifest.webmanifest
theme-color: #0f766eA `<script type="application/json">` is never run, so it's a handy place to keep data in a page. DevTools → Application → Manifest does these checks for real.
Preview
Console
Nothing logged yet.Expected console output
has a name: true
has start_url: true
app-like display: true
192px icon: true
512px icon: true
maskable icon: falseBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
A trailing comma in the manifest
In the manifest checker, add a comma after the last item of icons.
Break #2
A transparent Apple icon
Use a PNG with a transparent background as apple-touch-icon.
Myth vs fact
Myth
You need 20 different favicon files.
Fact
Old generators produced dozens. Today an ICO, an SVG, a 180 px Apple PNG and two manifest PNGs (192 and 512, plus a maskable one) cover every current browser.
Myth
A manifest makes the site work offline.
Fact
The manifest only describes the app. Working offline needs a service worker (a script that can answer requests from a cache), which is a JavaScript topic.
Myth
theme-color changes the page's background.
Fact
It only suggests a colour for the browser's own interface (address bar, app title bar). Your page's colours come from CSS.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
The manifest is fetched without cookies by default. If it's behind a login, add
crossorigin="use-credentials"to the manifest link, or the fetch fails. - ▸
Set an
idin the manifest (for example"id": "/"). Browsers identify an installed app byid, falling back tostart_url; if you later changestart_urlwithout anid, browsers see a different app. - ▸
Favicons are cached aggressively and separately from the page. When you change one, rename the file (
icon-v2.svg) or add a query string, or users will see the old icon for weeks. - ▸
In Next.js App Router, files named
icon.svg,apple-icon.png,favicon.icoandmanifest.tsinapp/generate these tags for you. Hectal usesfavicon.ico,apple-icon.pngandmanifest.tsthis way.
Remember this
- 1
A favicon (from "favourite icon") is the small picture on a browser tab, in bookmarks and in history. If a page has no icon link, browsers ask for
/favicon.icoat the root of the site anyway, so a missing one fills your server logs with 404s. The.icoformat can hold several sizes in one file (16, 32 and 48 pixels). - 2
Icons are added with
<link rel="icon">. Thesizesattribute says the pixel size (sizes="32x32", orsizes="any"for SVG), andtypesays the format. An SVG icon is one small vector file that stays sharp at every size and can even switch colours for dark mode with aprefers-color-schememedia query inside it. Chromium browsers and Firefox support SVG favicons; keep the.icoas a fallback for browsers that don't. - 3
<link rel="apple-touch-icon" href="/apple-touch-icon.png">is the icon iPhones and iPads use when someone adds your site to the home screen. Make it a 180 × 180 PNG with a solid background: iOS rounds the corners itself and fills transparent areas with black. - 4
<meta name="theme-color" content="#0f766e">suggests a colour for the browser's interface around your page, such as the address bar on Android Chrome and the title bar of an installed app. Add amediaattribute to give one colour for light mode and another for dark mode. Desktop browser tabs mostly ignore it. - 5
The web app manifest is a JSON file (JSON is a text format for data with
"key": valuepairs) linked with<link rel="manifest" href="/manifest.webmanifest">. It describes the site as an app:nameandshort_name(for small spaces under the icon),start_url(the page that opens),display(standalonehides the browser bars; others arefullscreen,minimal-uiandbrowser),background_color(the splash screen while it starts),theme_color, andiconswith at least a 192 × 192 and a 512 × 512 PNG. A site with a manifest like this, served over HTTPS, can be installed as a Progressive Web App (PWA). - 6
Android may cut icons into circles, squircles or rounded squares. An icon with
"purpose": "maskable"is designed for that: its important part sits inside a central safe zone (a circle 80% of the icon's width), and the background fills the whole square. Provide a normal (any) icon and a separate maskable one rather than one icon for both.
Explain it without notes
Which icon files does a modern site need, and what is each one for?
What does theme-color do, and how do you give different colours for light and dark mode?
What fields does a manifest need for a site to be installable in Chrome?
What is a maskable icon and why does it need a safe zone?
Practice
Write the head tags for a site's icons: an ICO fallback, an SVG, an Apple icon and a manifest, plus a light and a dark theme colour (#1d4ed8 and #0b1120).
Write a manifest for a to-do app called Tickit that opens /today in standalone mode, with a white background, a blue theme and the two required icon sizes.
Trade-offs
- ↔
An SVG favicon is one tiny file that adapts to dark mode, but not every browser uses it, so you still ship an ICO fallback.
- ↔
display: standalonemakes an installed site feel like an app, but it removes the back button and address bar, so your own navigation must handle everything.
Done when you can
I can write the modern minimal favicon set.
I can make a 180 px Apple icon that looks right on iOS.
I can set light and dark
theme-colorvalues.I can write and link a valid manifest with 192 and 512 px icons.
I can check icons and the manifest in DevTools → Application.