Adding a favicon should take two minutes, yet most tutorials still hand you a wall of fifteen <link> tags copied from 2014. Half of those tags target browsers that no longer exist. This guide gives you one copy-paste favicon HTML code snippet, a table of the file sizes that are actually required in 2026, and the Express configuration to serve them correctly.
The short answer: the favicon HTML code you need
Place this inside the <head> of every page (or in your layout template). Four lines, four files, every modern browser and device covered.
<!-- Classic favicon for browser tabs and bookmarks -->
<link rel="icon" href="/favicon.ico" sizes="32x32">
<!-- Modern scalable icon (supports dark mode) -->
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<!-- iOS / iPadOS home screen -->
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Android, Chrome, PWA install prompts -->
<link rel="manifest" href="/manifest.webmanifest">
Three things to check before you move on:
- The tags must be inside
<head>, not<body>. - Use absolute paths starting with a slash (
/favicon.ico), notfavicon.ico. Relative paths break on nested URLs such as/blog/post/. - The four files live at the root of your public directory, so they resolve at
https://example.com/favicon.ico.

What each line actually does
1. favicon.ico
The ICO file is still the most reliable fallback. Browsers request /favicon.ico automatically even if you never declare it, and some crawlers, RSS readers, feed aggregators and email clients only look for that file. Keep it as a multi-resolution ICO containing 16×16, 32×32 and 48×48 layers. The sizes="32x32" hint tells Chrome and Firefox which layer to prefer, which avoids blurry upscaled tabs on high-DPI screens.
2. icon.svg
An SVG favicon scales perfectly on every pixel density and supports a dark mode variant inside the file itself. Chrome, Edge, Firefox, Opera and Safari all support it. Browsers that do not will silently fall back to the ICO, which is why both lines belong in your snippet.
3. apple-touch-icon.png
This is the icon iOS uses when a visitor taps Add to Home Screen. One 180×180 PNG is enough. iOS downscales it for smaller devices. Do not add transparency: iOS fills transparent pixels with black. Use a solid background and keep the corners square, because the system applies its own rounding.
4. manifest.webmanifest
Android and Chromium-based browsers read the manifest instead of <link> tags for home screen and install icons. This is also what makes your site installable as a PWA.
Favicon sizes: the only files you need in 2026
| File | Size | Format | Used by | Required? |
|---|---|---|---|---|
favicon.ico |
16×16, 32×32, 48×48 in one file | ICO | Browser tabs, bookmarks, history, crawlers, feed readers | Yes |
icon.svg |
Any (vector), design on a 32×32 grid | SVG | All modern desktop and mobile browsers, dark mode | Recommended |
apple-touch-icon.png |
180×180 | PNG (no alpha) | iOS and iPadOS home screen, Safari shared links | Yes |
icon-192.png |
192×192 | PNG | Android home screen, manifest | Yes |
icon-512.png |
512×512 | PNG | PWA splash screens, app listings, install dialog | Yes |
icon-maskable-512.png |
512×512 with 20% safe padding | PNG | Android adaptive icons (circle, squircle, teardrop masks) | Optional but strongly advised for PWAs |
That is six files maximum, and realistically four if you are not shipping a PWA. Anything beyond this list is legacy baggage.

The web app manifest
Create manifest.webmanifest at the root of your public folder:
{
"name": "Your Site Name",
"short_name": "YourSite",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0b5fff",
"icons": [
{ "src": "/icon-192.png", "type": "image/png", "sizes": "192x192" },
{ "src": "/icon-512.png", "type": "image/png", "sizes": "512x512" },
{ "src": "/icon-maskable-512.png", "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
]
}
Notes that save debugging time:
- The manifest must be served with the
application/manifest+jsonMIME type. Express does this automatically for the.webmanifestextension in recent versions ofmime-db, but check your response headers. - If your manifest sits on another origin or you fetch it with credentials, add
crossorigin="use-credentials"to the link tag. - A maskable icon needs its artwork inside the central 80% circle, otherwise Android will crop your logo.
Dark mode favicons the clean way
You do not need extra HTML. Put a media query inside the SVG file itself, and the icon reacts to the operating system theme:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
circle { fill: #0b1220; }
@media (prefers-color-scheme: dark) {
circle { fill: #ffffff; }
}
</style>
<circle cx="16" cy="16" r="14"/>
</svg>
Keep SVG favicons extremely simple. At 16 pixels, gradients, thin strokes and text turn into mush. One shape, one or two colors, high contrast.
Tags you can delete in 2026
If your <head> contains any of the following, remove them. They add bytes and parsing work for zero benefit.
| Legacy tag or file | Why it is obsolete |
|---|---|
rel="shortcut icon" |
Invalid keyword kept alive only for Internet Explorer. rel="icon" is the standard. |
rel="mask-icon" (Safari pinned tab SVG) |
Deprecated since Safari 12. Safari now uses your regular icons. |
msapplication-TileImage, browserconfig.xml |
Windows 8 and 10 live tiles no longer exist. |
| The 10 apple-touch-icon sizes (57, 60, 72, 76, 114, 120, 144, 152 and so on) | iOS downscales a single 180×180 PNG perfectly. |
apple-touch-icon-precomposed |
iOS stopped applying gloss effects years ago. |
android-chrome-192x192.png declared with a link tag |
Android reads the manifest, not link tags. |

Serving your favicon correctly with Express
Favicon problems are very often server problems, not HTML problems. In an Express app, put the icon files in your static directory root:
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public'), {
maxAge: '30d',
etag: true
}));
app.listen(3000);
With public/favicon.ico, public/icon.svg, public/apple-touch-icon.png, public/icon-192.png, public/icon-512.png and public/manifest.webmanifest in place, every path in the snippet resolves. (via https://coddy.tech)
Avoiding the 404 flood in your logs
Browsers request /favicon.ico on their own. If the file is missing, your logs fill with 404 lines and your error handler may be triggered on every page view. Two options:
- Ship the file. The simplest and best fix.
- Return a 204 explicitly while you are still designing the icon:
app.get('/favicon.ico', (req, res) => res.status(204).end());
Register that route before your catch-all handlers so it is not swallowed by a wildcard route.
Caching strategy
- Give
favicon.icoandicon.svga moderate cache (a few days). Browsers cache favicons aggressively anyway. - If you rebrand, do not fight the cache. Rename the file (
icon-v2.svg) or add a query string:/icon.svg?v=2. - Never serve an icon behind authentication middleware. Mount
express.staticbefore your auth layer, or the browser gets a redirect and shows the default globe.
How to generate the files in five steps
- Start from a square vector logo (SVG or AI). Never upscale a small PNG.
- Create a simplified mark for small sizes: remove text, keep one symbol, increase stroke weight.
- Export
icon.svgwith aviewBox="0 0 32 32"and no external fonts (convert text to paths). - Export PNGs at 180, 192 and 512 pixels, plus a maskable version with 20% padding on all sides.
- Build the multi-layer
favicon.ico(16, 32, 48) with any favicon generator or ImageMagick:magick icon-512.png -define icon:auto-resize=48,32,16 favicon.ico

Troubleshooting: favicon not showing up
- Hard refresh is not enough. Favicons use a separate cache. Open the icon URL directly (
https://yoursite.com/favicon.ico) to confirm it loads, then test in a private window. - Check the response status and MIME type in the Network tab. An HTML 404 page returned with a 200 status is the classic silent failure.
- Wrong path. A Windows style path such as
C:\icons\favicon.icoor a backslash anywhere in thehrefwill never resolve on a server. - Mixed content. An
http://icon URL on anhttps://page gets blocked. - Case sensitivity. Linux servers treat
Favicon.ICOandfavicon.icoas different files. - Google search results. Google crawls your favicon separately and needs the icon to be reachable, at least 8×8 pixels, a multiple of 48 for best results, and it can take days to update.
Final checklist
- Four
<link>tags in<head>, absolute paths. - Six icon files at the root of your public folder.
- Manifest served as
application/manifest+json. - No legacy tile, precomposed or mask-icon tags.
- Apple touch icon with an opaque background.
- Tested in a private window on desktop, iOS and Android.
FAQ
What is a favicon in HTML?
A favicon is the small icon a browser displays in the tab, bookmark list, history and address bar suggestions. In HTML it is declared with a <link rel="icon"> tag inside the <head> element, pointing to an ICO, PNG or SVG file.
Can a favicon be 512×512?
Yes. A 512×512 PNG is valid and is in fact the recommended size for the web app manifest, PWA install dialogs and Android splash screens. Browsers downscale it for the tab. For the tab itself, a 32×32 ICO or an SVG stays sharper because you control how the small version looks.
Do I still need favicon.ico in 2026?
Yes. Even though every modern browser supports PNG and SVG icons, browsers and bots still request /favicon.ico by default, and several tools (feed readers, link preview services, some email clients) only look for that file. It costs a few kilobytes.
How do I add my logo as a favicon in HTML?
Export a square, simplified version of your logo, generate the ICO, SVG and PNG files listed in the table above, upload them to the root of your public directory, then paste the four line snippet into your <head>. Do not reference your full-size logo file directly: a 2 MB PNG as a favicon slows down every page load. ccbill.com has covered this at length.
How do I fix a favicon.ico error?
A favicon 404 means the browser asked for /favicon.ico and your server did not return a file. Place a real favicon.ico at the root of your static folder, verify that your static middleware is mounted before any authentication or wildcard routes, and confirm the URL loads in a browser tab on its own. As a temporary measure you can return a 204 No Content response for that route.
SVG or PNG: which one should I declare first?
Order the tags ICO first, then SVG. Browsers that support SVG will pick it because it is the more specific and higher quality option, while older clients fall back to the ICO. Both lines together cover everything without any scripting or user agent detection.
Where exactly do I put the favicon code?
Inside <head>, ideally near the top with your charset and viewport meta tags. In a templating setup (Pug, EJS, Handlebars, Nunjucks) put it in your base layout so every page inherits it automatically.
