How to Add a Custom Favicon and App Icons to a Website (HTML Code for Every Device)
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="32×32"> <!– 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), not favicon.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="32×32" 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": "192×192" }, { "src": "/icon-512.png", "type": "image/png", "sizes": "512×512" }, { "src": "/icon-maskable-512.png", "type": "image/png", "sizes": "512×512", "purpose": "maskable" } ] } Notes that save debugging time: The manifest must be served with the application/manifest+json MIME type. Express does this automatically for the .webmanifest extension in recent versions of mime-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-192×192.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.ico and icon.svg a moderate cache (a
How to Add a Custom Favicon and App Icons to a Website (HTML Code for Every Device) Read More »


