How to Add a Favicon to Any Website
Adding a favicon is three jobs: put the files where the server can reach them, declare them in the page head, and check they load. Here is each job for hand-written HTML, the common frameworks and the hosted platforms.
Step 1: Get the files
Create them from text, an emoji or your logo in the favicon generator, or convert an existing logo with SVG to favicon. The download is a ZIP with every file below except the SVG, which you only have if your logo is already a vector file.
| File | Size | Used for | Needed? |
|---|---|---|---|
| favicon.ico | 16, 32, 48, 64 px layers | Default /favicon.ico request, older browsers, Windows | Yes |
| favicon-32x32.png | 32×32 | Browser tabs on high-density screens | Yes |
| favicon-16x16.png | 16×16 | Browser tabs at standard density | Recommended |
| apple-touch-icon.png | 180×180 | iPhone and iPad home screen | Yes |
| android-chrome-192x192.png | 192×192 | Android home screen (via manifest) | Yes |
| android-chrome-512x512.png | 512×512 | Android splash screen and install (via manifest) | Yes |
| site.webmanifest | JSON | Lists the Android icons, name and colours | Yes |
| favicon.svg | Vector | Sharp, dark-mode-aware tab icon in modern browsers | Optional extra |
Why these sizes and not others: favicon sizes guide.
Step 2: Plain HTML
Copy the files into the folder that holds your homepage, so the structure looks like this:
your-site/ ├── index.html ├── about.html ├── favicon.ico ├── favicon-16x16.png ├── favicon-32x32.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png └── site.webmanifest
Then paste these tags inside <head> on every page (or in your shared header template):
<link rel="icon" href="/favicon.ico" sizes="32x32"> <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="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="manifest" href="/site.webmanifest"> <meta name="theme-color" content="#2563eb">
- Every
hrefstarts with/so the tags work on nested pages too. - Have an SVG logo as well? Upload it as
favicon.svgand add<link rel="icon" href="/favicon.svg" type="image/svg+xml">. Keepsizes="32x32"on the ICO line — withsizes="any"Chrome picks the ICO over the SVG. - Change
theme-colorto your brand colour; mobile browsers tint their toolbar with it.
Next.js (App Router)
Next.js writes the tags for you when icon files sit in the app/ folder with specific names. Rename two files from the ZIP:
app/ ├── favicon.ico ← favicon.ico from the ZIP ├── icon.png ← android-chrome-192x192.png, renamed ├── apple-icon.png ← apple-touch-icon.png, renamed └── layout.tsx public/ ├── android-chrome-192x192.png ├── android-chrome-512x512.png └── site.webmanifest
// app/layout.tsx
export const metadata = {
manifest: '/site.webmanifest',
};Do not also add manual <link rel="icon"> tags or an icons object in metadata — you would get two competing sets. A leftover app/favicon.ico from create-next-app is the usual reason the Next.js logo keeps appearing after you add your own icon somewhere else.
Vite, React, Vue and other single-page apps
Copy the files into public/ and put the HTML tags from Step 2 in the root index.html. Files in public/ are copied to the build output unchanged, so public/favicon.ico is served at /favicon.ico.
New Vite projects ship with <link rel="icon" href="/vite.svg"> in index.html. Delete that line, or the Vite logo wins in Chrome no matter what else you add. If the app is deployed under a sub-path, read the GitHub Pages note below and check the hrefs in the built dist/index.html.
GitHub Pages and other sub-folder hosting
A project site lives at username.github.io/project/, but href="/favicon.ico" points at username.github.io/favicon.ico — a different site. Either include the folder (/project/favicon.ico) or attach a custom domain so the project is served from the root. The same applies to any site hosted in a sub-folder of another domain.
WordPress
Use the built-in Site Icon: Appearance → Customize → Site Identity → Site Icon, upload a 512×512 PNG and publish. WordPress generates the 32, 180, 192 and 270 px versions and prints the tags. The WordPress favicon guide shows the exact output and how to add an SVG.
Shopify
Upload a square PNG in Online Store → Themes → Customize → Theme settings (under Logo in Dawn). Shopify only outputs a 32×32 PNG from it; the Shopify favicon guide has the theme.liquid lines that add a 192 px icon for Google and an Apple touch icon.
Squarespace, Wix, Webflow and other site builders
Hosted builders do not let you upload files to the site root or edit the icon tags directly. Look for a setting called Favicon or Browser icon in the site settings, and upload a single square PNG of 512×512 px; the platform resizes it. Some builders have a second field for the home-screen icon (Webflow calls it the webclip) — use the 180×180 apple-touch-icon.png there. Wix only shows a custom favicon on premium plans with a connected domain.
Menu names change often on these platforms. If you cannot find the setting, search the platform's help centre for "favicon".
Step 3: Verify it works
- Open
yourdomain.com/favicon.icoandyourdomain.com/apple-touch-icon.pngin a private window. You should see the image, not a 404 page or your homepage. - View the page source of an inner page and check every icon href starts with
/. - Run the favicon checker on your URL. It confirms each declared file loads and gives you an HTML fix for anything missing.
- In Chrome DevTools, open Application → Manifest to confirm the 192 and 512 px icons load.
- Still seeing the old icon? That is cache — the favicon not showing guide covers clearing it in each browser.
Common mistakes
- Relative paths.
href="favicon.png"works on the homepage and breaks one folder down. - A framework's default icon left behind. vite.svg, app/favicon.ico or a theme's bundled icon keeps winning over yours.
- Renaming a PNG to .ico. Some browsers accept it, Windows and many tools do not. Build a real ICO with the PNG to ICO converter.
- A transparent apple-touch-icon. iOS fills transparency with black. Give the 180×180 file a solid background.
- Mismatched manifest paths. The
srcvalues inside site.webmanifest must match where you uploaded the PNGs.