How to Add a Favicon to Your Website: The Complete HTML Implementation Guide
You have a favicon file. Maybe you designed it yourself, maybe a designer handed it to you, or maybe you just generated one. Now you're staring at your HTML file wondering: where does this thing actually go?
Adding a favicon seems like it should be simple—and at its core, it is. But the gap between "technically works" and "works perfectly everywhere" is where most websites stumble. I've seen favicons fail on Safari while working on Chrome, disappear on mobile devices, or simply refuse to update no matter how many times you refresh.
This guide gives you the complete implementation, from the basic one-liner that gets you started to the production-ready setup that covers every browser and platform. You'll learn exactly which HTML tags to use, where to place your files, and how to verify everything works before your visitors ever see it.
The Basic Favicon Implementation (60-Second Version)
Let's start with the minimum viable favicon. If you just want something working right now, here's what you need:
- Name your favicon file
favicon.ico - Place it in your website's root directory (same level as your homepage)
- That's it—seriously
Browsers have automatically looked for /favicon.ico since Internet Explorer 5 introduced favicons in 1999. No HTML required. If that file exists at your root, browsers will find it and display it.
But here's why you shouldn't stop there: this approach only gives you the basic browser tab icon. You'll miss out on:
- High-resolution icons for retina displays
- Apple Touch Icons for iOS home screens
- Android icons for "Add to Home Screen"
- Proper icons for bookmarks and reading lists
- Windows tile icons
For a professional website, you need the full implementation.
The Complete Favicon HTML Code
Here's the production-ready HTML that covers all major browsers and platforms. Place this in the <head> section of every page:
<head>
<!-- Basic favicon -->
<link rel="icon" href="/favicon.ico" sizes="48x48">
<!-- Modern browsers (SVG for scaling + PNG fallback) -->
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon-96x96.png" sizes="96x96" type="image/png">
<!-- Apple Touch Icon -->
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<!-- Web App Manifest (for Android and PWAs) -->
<link rel="manifest" href="/site.webmanifest">
</head>
Let me break down exactly what each line does and why it matters.
Understanding Each Favicon Link Tag
The Classic ICO Fallback
<link rel="icon" href="/favicon.ico" sizes="48x48">
The .ico format remains the universal fallback. While modern browsers handle PNG and SVG beautifully, ICO ensures compatibility with:
- Internet Explorer (all versions)
- Older corporate browsers and embedded systems
- Some RSS readers and bookmarking tools
- Edge cases in automated crawlers and scrapers
The sizes="48x48" attribute tells browsers this icon's intended size. Modern ICO files often contain multiple sizes bundled together (16x16, 32x32, 48x48), but declaring the size helps browsers make smarter choices.
SVG for Modern Browsers
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
SVG favicons are the future. They scale perfectly to any size, support CSS media queries for dark mode adaptation, and typically have smaller file sizes than equivalent PNGs.
Browser support as of 2024:
- Chrome 80+: Full support
- Firefox 41+: Full support
- Safari 12+: Full support
- Edge 80+: Full support
- Opera 67+: Full support
The type="image/svg+xml" attribute is technically optional but helps browsers identify the format without downloading the file first.
High-Resolution PNG
<link rel="icon" href="/favicon-96x96.png" sizes="96x96" type="image/png">
This PNG serves browsers that don't support SVG favicons and provides a crisp icon for high-DPI displays. The 96x96 size works well because it scales down cleanly to 32x32 and 48x48.
Why include this when we have SVG? A few reasons:
- Some browsers prefer PNG over SVG in certain contexts
- Provides a guaranteed pixel-perfect render at specific sizes
- Acts as a reliable fallback if anything goes wrong with SVG loading
Apple Touch Icon
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
This is non-negotiable if any of your users have iPhones or iPads. When someone adds your website to their iOS home screen, Safari uses this icon—not your favicon.
Apple Touch Icons should be:
- Exactly 180x180 pixels
- PNG format (required)
- No transparency (iOS adds its own effects)
- No rounded corners (iOS applies these automatically)
The apple-touch-icon relationship is specific to Apple devices. Regular favicon declarations won't work for iOS home screens.
Web App Manifest
<link rel="manifest" href="/site.webmanifest">
The manifest file handles Android Chrome's "Add to Home Screen" feature and is essential for Progressive Web Apps (PWAs). It's a JSON file that references your icons:
{
"name": "Your Site Name",
"short_name": "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"
}
Save this as site.webmanifest in your root directory. Android requires at least a 192x192 icon, but including 512x512 ensures crisp display on high-resolution devices and is required for PWA installability.
Where to Place Your Favicon Files
File placement matters more than most guides acknowledge. Here's the ideal structure:
your-website/
├── index.html
├── favicon.ico
├── favicon.svg
├── favicon-96x96.png
├── apple-touch-icon.png
├── android-chrome-192x192.png
├── android-chrome-512x512.png
└── site.webmanifest
Why the root directory? Several reasons:
- Browsers automatically check
/favicon.icobefore even reading your HTML - Some older systems and crawlers only look in the root
- Simpler paths reduce the chance of typos breaking things
- CDN and caching configurations are more straightforward
Can you use a subdirectory? Technically yes. This works:
<link rel="icon" href="/assets/images/favicon.ico">
But be aware that:
- The automatic
/favicon.icolookup won't find it - Every path in your manifest file must be updated
- Some edge cases in older browsers may fail
- It adds complexity with no real benefit
My recommendation: keep favicons in the root. The small "clutter" is worth the reliability.
Adding Favicons to Every Page
Your favicon HTML needs to appear on every page of your website. How you accomplish this depends on your setup:
Static HTML Sites
If you're hand-coding HTML files, you'll need to include the favicon tags in each page's <head>. This is tedious, which is why most developers use a templating approach or static site generator.
PHP / Server-Side Includes
<!-- header.php -->
<head>
<?php include 'favicon-tags.html'; ?>
<!-- other head content -->
</head>
JavaScript Frameworks (React, Vue, Next.js, etc.)
Most frameworks have a root HTML template or head management system:
Next.js (App Router):
// app/layout.js
export const metadata = {
icons: {
icon: [
{ url: '/favicon.ico', sizes: '48x48' },
{ url: '/favicon.svg', type: 'image/svg+xml' },
],
apple: '/apple-touch-icon.png',
},
}
React (Create React App):
Place files in the public/ folder and add link tags to public/index.html.
Vue:
Add link tags to your root index.html file.
Content Management Systems
WordPress, Shopify, Squarespace, and similar platforms typically have built-in favicon settings in their admin panels. However, these often only handle basic favicons—you may need to manually add Apple Touch Icon and manifest links to your theme's header.
Verifying Your Favicon Implementation
After adding your favicon code, don't just refresh the page and assume it works. Here's a proper verification process:
Step 1: Clear Your Browser Cache
This is crucial. Browsers aggressively cache favicons, sometimes for weeks. In Chrome:
- Open DevTools (F12)
- Right-click the refresh button
- Select "Empty Cache and Hard Reload"
Or use an incognito/private window—this ignores cached favicons entirely.
Step 2: Check the Network Tab
With DevTools open, go to the Network tab, reload the page, and filter by "img" or search for "favicon". You should see requests for your favicon files with 200 status codes.
If you see 404 errors, your file paths are wrong. If you see the requests succeeding but the wrong icon appears, you have a caching issue or duplicate declarations.
Step 3: Test on Real Devices
Browser DevTools can simulate mobile, but nothing replaces testing on actual devices:
- iPhone: Add to Home Screen, verify the Apple Touch Icon appears correctly
- Android: Same test—the manifest icon should display
- Multiple desktop browsers: Check Chrome, Firefox, Safari, and Edge
Step 4: Use a Favicon Checker Tool
Several online tools crawl your site and verify all favicon implementations. They'll catch issues like missing manifest icons or incorrectly sized Apple Touch Icons that manual testing might miss.
Common Implementation Mistakes (And How to Avoid Them)
After reviewing thousands of favicon implementations, these are the errors I see most frequently:
Mistake 1: Using Relative Paths
<!-- Problematic -->
<link rel="icon" href="favicon.ico">
<!-- Better -->
<link rel="icon" href="/favicon.ico">
Without the leading slash, the path is relative to the current page's directory. Your favicon might work on the homepage but break on /blog/my-post/.
Mistake 2: Forgetting the Type Attribute
While browsers can usually detect file types, explicitly declaring them prevents edge cases:
<link rel="icon" href="/favicon.png" type="image/png">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
Mistake 3: Using "shortcut icon" Instead of "icon"
You might see this in older tutorials:
<link rel="shortcut icon" href="/favicon.ico">
The "shortcut" part was an Internet Explorer quirk and is now obsolete. Modern HTML should use just rel="icon". Browsers still support the old syntax, but there's no reason to use it.
Mistake 4: Not Including Sizes
When you have multiple favicon declarations, the sizes attribute helps browsers choose:
<link rel="icon" href="/favicon-16x16.png" sizes="16x16" type="image/png">
<link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png">
Without sizes, browsers may choose arbitrarily—often picking the last one declared.
Mistake 5: SVG Favicon Without PNG Fallback
SVG favicons are great, but browser support isn't 100%. Always include a PNG or ICO fallback before your SVG declaration:
<link rel="icon" href="/favicon.ico" sizes="48x48">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
Browsers use the last compatible declaration, so SVG-capable browsers will use the SVG while others fall back to ICO.
Advanced: Conditional Favicons
Sometimes you need different favicons for different situations.
Development vs. Production
A different favicon for your staging environment prevents confusion:
<!-- In your build process or server config -->
<?php if (getenv('APP_ENV') === 'development'): ?>
<link rel="icon" href="/favicon-dev.svg" type="image/svg+xml">
<?php else: ?>
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<?php endif; ?>
Dark Mode Support (via SVG)
SVG favicons can include CSS that responds to the user's color scheme:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
path { fill: #000000; }
@media (prefers-color-scheme: dark) {
path { fill: #ffffff; }
}
</style>
<path d="..."/>
</svg>
This single SVG file automatically adapts to light and dark modes—no JavaScript required.
Dynamic Favicons with JavaScript
You can change favicons programmatically for notifications or state changes:
function setFavicon(url) {
let link = document.querySelector("link[rel~='icon']");
if (!link) {
link = document.createElement('link');
link.rel = 'icon';
document.head.appendChild(link);
}
link.href = url;
}
// Example: Show notification badge
setFavicon('/favicon-notification.png');
This technique powers the notification badges you see on sites like Gmail or Slack.
Ready to Create Your Favicon?
Now you know exactly how to implement a favicon—the HTML tags, file placement, and verification process. The implementation is the easy part once you have a well-designed favicon to work with.
If you haven't created your favicon yet, our favicon generator can help. Generate dozens of unique favicon ideas in seconds, pick the one that matches your brand, and download all the sizes and formats covered in this guide—ready to implement with the exact code we've discussed.
Frequently Asked Questions
Do I need to add favicon code to every HTML page?
Yes, the favicon link tags should appear in the <head> section of every page. Most websites accomplish this through templates, includes, or framework-level head management rather than manually editing each page.
Why isn't my new favicon showing after I uploaded it?
Browser caching is almost always the culprit. Browsers cache favicons aggressively—sometimes for weeks. Clear your cache, use an incognito window, or add a query string like ?v=2 to force a refresh during development.
Can I use a JPG file as a favicon?
Technically some browsers will display JPEG favicons, but it's not recommended. JPG doesn't support transparency, and browser support is inconsistent. Stick with ICO, PNG, or SVG for reliable results.
What's the minimum favicon implementation that actually works?
At absolute minimum: place a file named favicon.ico in your root directory. Browsers will find it automatically. However, this misses Apple Touch Icons, Android home screen icons, and high-resolution support. The full implementation in this guide takes only a few extra minutes and covers all platforms properly.
Should I use favicon.ico or favicon.png for the main browser icon?
For maximum compatibility, use both. Declare the ICO first as a fallback, then PNG (or SVG) as the preferred modern option. Browsers will use the best option they support while older systems fall back to ICO.