Skip to main content

How to Add a Favicon to Your Website (HTML)

8 min read

To add a favicon in HTML, place <link rel="icon"> tags in your document <head>, add apple-touch-icon for iOS, link a web manifest for Android/PWA icons, and upload favicon.ico to your site root. Browsers discover icons from these tags plus the automatic /favicon.ico request.

Below is a complete, production-ready setup you can paste and adapt. After deploy, scan the live URL with Favicon Check to confirm every file resolves.

Minimal setup (fastest path)

If you need something working in five minutes:

<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">

Upload three files to your web root:

  • /favicon.ico
  • /favicon-32x32.png (32×32 px)
  • /apple-touch-icon.png (180×180 px)

That covers basic desktop tabs and iOS home screens. It is not the full modern set. For 192×512 manifest icons and 16×16 tabs, use the full template in the next section.

Full HTML template (recommended)

Put this inside <head>, ideally before CSS links so browsers discover icons early:

<!-- Standard favicons -->
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<!-- Optional: SVG for modern browsers -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<!-- iOS home screen -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<!-- Android / PWA -->
<link rel="manifest" href="/site.webmanifest">
<!-- Optional: Safari pinned tab -->
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000">

Pair it with a site.webmanifest at the same origin:

{
"name": "My Site",
"short_name": "My Site",
"icons": [
{
"src": "/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

File size reference: see the Favicon Sizes Guide for when each dimension appears.

Where to put favicon tags in HTML

Favicons belong in <head>, not <body>. Browsers parse the head before first paint. Icons referenced late in the document may flash a generic icon on slow connections.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example</title>
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<!-- other head content -->
</head>
<body>
...
</body>
</html>

Path rules

  • Root-relative paths (/favicon-32x32.png) work on most sites and survive page depth.
  • Absolute URLs (https://cdn.example.com/icons/favicon-32x32.png) work when served from a CDN. Every icon URL must be HTTPS in production.
  • Relative paths (./favicon.ico) break on nested routes like /blog/post-slug unless you calculate depth. Prefer root-relative paths.

Wrong paths are the top cause of "favicon not showing" reports. After every deploy, run Favicon Check on a deep URL (not only the homepage) to confirm paths resolve from every route.

Understanding each link tag

rel="icon"

The default favicon for browser tabs and bookmarks.

<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">

The sizes attribute should match the real image dimensions. Mismatched values confuse audit tools and sometimes browser selection logic.

rel="shortcut icon"

Legacy HTML4 syntax. Still recognized, but rel="icon" is enough today. If you use both, point them at the same file.

<link rel="shortcut icon" href="/favicon.ico">

rel="apple-touch-icon"

Used when iOS users tap "Add to Home Screen." Not interchangeable with rel="icon".

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">

rel="manifest"

Links to your JSON manifest. The manifest holds 192×192 and 512×512 icons for Android and PWAs.

<link rel="manifest" href="/site.webmanifest">

Serve the manifest with Content-Type: application/manifest+json or application/json.

rel="mask-icon"

Monochrome SVG for Safari pinned tabs on macOS. Niche but expected on some editorial sites.

<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">

favicon.ico at the site root

Even with perfect link tags, browsers and bots request:

https://yourdomain.com/favicon.ico

Place the file at the root of your origin. If your site is a SPA on a subpath only, the ICO still belongs at the domain root unless you control redirects.

The Favicon Check explicitly probes /favicon.ico when it is not declared in HTML. If you rely on ICO only, the scanner still finds it.

Step-by-step implementation

1. Export your icon files

Start from a 512×512 master. Export PNGs at 16, 32, 180, 192, and 512 px. Generate favicon.ico with embedded 16/32/48 layers. Optional: export favicon.svg for sharp desktop rendering.

Use the size lab on Favicon Check to preview uploads at tab and home screen sizes before committing files.

2. Upload to static hosting

Put files on the same origin as your HTML or on a CDN you control. Ensure public HTTPS access with no auth wall.

3. Add tags to your layout template

If you use a shared layout (WordPress header, Rails layout, Next.js app/layout.tsx), add tags once globally. Do not duplicate per page.

4. Deploy and bust cache if needed

Favicons cache hard. After a rebrand, use new filenames or short cache TTLs on icon paths during the transition.

5. Validate the live site

  1. Open Favicon Check.
  2. Paste your production URL.
  3. Confirm every expected file appears with correct rel and sizes.
  4. Download any suspicious entry and open it locally.
  5. Run the Open Graph scanner on the same URL to verify social previews while you are auditing.

Framework-specific notes

Plain HTML / static sites

Add the full template to each page's <head> or use a build step that injects a shared partial. For Eleventy, Hugo, or Jekyll, put icons in /static or /public so they copy to the build root.

React SPA (Vite, CRA)

Place icons in public/. Vite serves public/favicon.ico at /favicon.ico automatically. You still need explicit link tags in index.html for PNG sizes and apple-touch-icon.

WordPress

Upload via Customizer or a child theme functions.php enqueue. Many themes only set favicon.ico. Override with the full tag set in header.php or a small plugin you control.

Next.js App Router

Place favicon.ico in app/. Use icon.png and apple-icon.png file conventions, or export metadata:

export const metadata = {
icons: {
icon: [
{ url: "/favicon-32x32.png", sizes: "32x32", type: "image/png" },
],
apple: "/apple-touch-icon.png",
},
manifest: "/site.webmanifest",
}

Framework guides with more detail are coming in our Next.js and WordPress favicon posts. The HTML output goal stays the same: correct files at correct URLs.

Common HTML mistakes

Icons only in JavaScript

Client-rendered link tags arrive too late. Crawlers, RSS readers, and some browsers never see them. Icons must be in server-rendered HTML.

Missing type attribute

Browsers usually guess from extension. Explicit type="image/png" or type="image/svg+xml" helps audit tools and validators.

Wrong MIME type on the server

If your server serves .ico as application/octet-stream, some tools complain. Configure image/x-icon for ICO and image/png for PNG.

Declaring sizes="any" on PNG

Reserve sizes="any" for ICO or SVG. PNG entries should use exact pixel sizes like 32x32.

Forgetting the manifest link

Developers add site.webmanifest to the repo but omit <link rel="manifest">. Android then ignores PWA icons. The Favicon Check surfaces manifest icons only when the link tag is present and JSON parses.

HTTP instead of HTTPS

Mixed-content policies block icons on secure pages. Serve everything over HTTPS.

HTML-only vs CMS vs framework

ApproachProsGotcha
Raw HTML in <head>Full control, easy to auditMust update every template manually
CMS customizerNo code for marketersOften sets only one small icon
Framework metadata APITyped, versioned in repoKnow what URLs the build emits

Regardless of approach, the verification step is identical: scan the public URL with Favicon Check.

Copy-paste checklist

  • favicon.ico exists at /favicon.ico
  • 32×32 and 16×16 PNG link rel="icon" tags in <head>
  • apple-touch-icon at 180×180
  • site.webmanifest with 192 and 512 icons
  • <link rel="manifest" href="/site.webmanifest"> present
  • All paths root-relative or absolute HTTPS
  • Live URL scanned with Favicon Check
  • Same URL scanned with Open Graph scanner for og:image

FAQ

How many link tags do I need?

At minimum three: ICO or 32×32 icon, apple-touch-icon, and manifest link. A full setup adds 16×16, optional SVG, and mask-icon.

Can I use only one <link rel="icon">?

Yes for basic tabs. iOS and Android still need their own tags or manifest entries.

Should favicon links go before or after CSS?

Before is slightly safer for earliest discovery. Order among head children rarely breaks modern browsers if all tags are in <head>.

Does every page need favicon tags?

Every HTML page should include them, usually via a shared layout. Missing tags on one template means wrong icons on whole sections of your site.

How do I add a favicon to a subdomain?

Each origin (subdomain) needs its own files and tags. app.example.com does not inherit www.example.com favicons automatically.

What if my site is behind a login wall?

Public favicons must be reachable without authentication. Test in an incognito window or with Favicon Check, which fetches as an anonymous crawler.

How do I update a favicon without users seeing the old one?

Change the filename (favicon-2026.ico), update href, and set shorter Cache-Control on icon paths during rollout.

Is a data URI favicon valid?

href="data:image/png;base64,..." works in some browsers but hurts caching and Content Security Policy setups. Static files on HTTPS are the standard approach.

Bottom line

Add rel="icon" PNGs, apple-touch-icon, manifest link, and root favicon.ico to your <head>. Use root-relative HTTPS paths, server-render the tags, and validate with Favicon Check after deploy. For the complete size breakdown, read the Favicon Sizes Guide. For social sharing, run the Open Graph scanner on the same URL.