html

Add a Favicon to HTML

Install a browser icon with correct paths and markup, expand it into a full Apple and PWA pack, configure responses, and verify the live deployment.

FaviconMaker Editorial Team

12 min read
#html#setup#generator#troubleshooting
Share this guide
Add a Favicon to HTML
On this page38 sections

Put the image in your site's published files and add this line inside the document's <head>:

<link rel="icon" type="image/png" href="/favicon.png" />

That is the smallest modern setup. The leading slash means “from this hostname's root,” so a page at /products/widget/ still requests https://example.com/favicon.png.

For broader browser, Apple home-screen, and installed-app coverage, use a small deliberate pack rather than one mystery file:

<link rel="icon" href="/favicons/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="64x64" href="/favicons/favicon-64x64.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
<link rel="manifest" href="/favicons/site.webmanifest" />
<meta name="theme-color" content="#ffffff" />

Generate those assets and a matching snippet with the Favicon Generator, then scan the public page with the Favicon Checker. The sections below explain every file, attribute, path rule, and test so you are not dependent on a copied snippet.

This guide is for static HTML, shared server templates, and developers who want to understand the markup beneath a framework. If a hosted CMS owns the document head, use its supported icon setting rather than editing generated output that the platform will replace.

First decide where the markup belongs

The icon declarations belong in the shared document <head>, not in the visible <body> and not on just one article page.

Site typePut files herePut declarations here
Hand-written static HTMLBeside published HTML or in /favicons/Inside <head> on every document, usually via a shared include
Server templatePublic/static directoryBase layout or head partial
Static-site generatorIts copied static-assets directoryGlobal layout/template
Next.js App RouterReserved files in app/, or files in public/File conventions or Metadata API
WordPressMedia/platform-managed locationSite Icon setting, theme API, or a child-theme head hook
Single-page appBuild tool's public/static directorySource index.html or framework metadata API

If a framework manages metadata, use its native API. Manually editing generated HTML is fragile because the next build overwrites it. Next.js users should follow the tested Next.js setup; platform users can use our WordPress, Shopify, Squarespace, or Wix guides.

Prepare artwork that survives tab size

Start from a square source, ideally a symbol rather than a full horizontal wordmark. Before export:

  • Use a 1:1 canvas.
  • Leave intentional breathing room around the mark.
  • Remove taglines and tiny lettering.
  • Thicken details that disappear when downsampled.
  • Check contrast on light and dark browser chrome.
  • Preview at 16x16 and 32x32, not only at 512x512.

SVG is useful as a master because it stays editable. Export purpose-built raster sizes from it; repeatedly resizing a tiny PNG upward cannot restore missing detail. For a wide brand lockup, make a dedicated symbol or monogram using the square logo design process.

What each file is for

You do not need every historical platform asset. This practical set covers the common jobs without confusing file count with quality.

FileTypical dimensionsMain jobKeep it when...
favicon.icoMultiple embedded sizesBroad browser and legacy fallbackAlmost always; it is compact compatibility insurance.
favicon-16x16.png16x16Small browser UIYou want explicit pixel-tuned tab artwork.
favicon-32x32.png32x32Browser UI and high-density tabsRecommended for a conventional pack.
favicon-48x48.png or largerSquareSearch and larger browser surfacesOrganic Search or larger UI surfaces matter.
apple-touch-icon.png180x180iOS/iPadOS saved home-screen iconUsers may save the site to a device home screen.
site.webmanifestJSONInstalled web-app name, colors, and icon candidatesThe product supports an installable/PWA experience.
192px and 512px app PNGs192x192, 512x512Installed-app and launcher surfacesReferenced by the manifest.
Maskable 512px PNG512x512 with safe zoneAdaptive launcher cropsYou support Android-style maskable installation.
browserconfig.xmlXMLHistorical Microsoft pinned-tile metadataA compatibility target still requires it.

An Apple touch icon and manifest icon are not substitutes for rel="icon". Each declaration addresses a different discovery system.

Inside the tested ZIP

Our July 19 pack contained:

favicon-pack/
├── README.txt
├── apple-touch-icon.png
├── browserconfig.xml
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon-48x48.png
├── favicon-64x64.png
├── favicon-96x96.png
├── favicon-128x128.png
├── favicon-256x256.png
├── favicon-512x512.png
├── favicon.ico
├── html-snippet.txt
└── site.webmanifest

The ZIP's exact byte size is not a quality target. Artwork complexity, transparency, compression, ICO contents, dark variants, and generator options all change it. The useful checks are that the referenced files exist, decode correctly, and suit their target surfaces.

Install a complete pack step by step

1. Copy files into the published asset directory

A clean deployment layout is:

site-root/
├── favicons/
│   ├── apple-touch-icon.png
│   ├── favicon-16x16.png
│   ├── favicon-32x32.png
│   ├── favicon-64x64.png
│   ├── favicon-192x192.png
│   ├── favicon-512x512.png
│   ├── favicon.ico
│   └── site.webmanifest
└── index.html

“Site root” here means the directory your web server publishes, not necessarily the repository root. In Vite it may be public/; in another build it may be copied into dist/; on shared hosting it may be public_html/.

After deployment, open https://example.com/favicons/favicon.ico directly. If that URL fails, do not change HTML yet. Fix file placement or server routing first.

2. Paste declarations into the shared head

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link rel="icon" href="/favicons/favicon.ico" sizes="any" />
    <link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png" />
    <link rel="icon" type="image/png" sizes="64x64" href="/favicons/favicon-64x64.png" />
    <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
    <link rel="manifest" href="/favicons/site.webmanifest" />
    <meta name="theme-color" content="#ffffff" />

    <title>Example site</title>
  </head>
  <body>
    ...
  </body>
</html>

Use rel="icon"; do not add rel="shortcut icon" just because an old tutorial does. The MDN rel reference calls the shortcut form a nonconforming historical alternative.

3. Make the manifest paths correct

{
  "name": "Example Site",
  "short_name": "Example",
  "icons": [
    {
      "src": "/favicons/favicon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any"
    },
    {
      "src": "/favicons/favicon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any"
    }
  ],
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display": "standalone"
}

Manifest src values resolve relative to the manifest URL, unless they start with / or are absolute. Root-relative paths remove ambiguity when a manifest lives inside /favicons/. The MDN manifest icon documentation describes sizes, type, and purpose.

Only set display: "standalone" when the site is designed and tested as an installed app. A manifest is product configuration, not an SEO decoration.

4. Deploy before evaluating the result

Check the public hostname after the build and upload. Local success does not prove that a Docker stage, ignore file, CDN rule, or static-host output directory included the assets.

A compact visual introduction to the basic HTML step. Use the path, platform, and production checks in this guide for the full deployment.

Watch on YouTube

Path resolution: the detail that breaks nested pages

We served two nested test pages from an in-memory HTTP server and inspected the resolved link URL in a real browser.

Test pageMarkupRequested URLResult
/guides/root/href="/favicon.png"/favicon.png200, image/png
/guides/relative/href="favicon.png"/guides/relative/favicon.png404, text/plain

This does not mean root-relative is always correct. Choose based on the deployment:

  • Root-relative /favicons/icon.png: best when the site owns the host root.
  • Path-relative ./favicons/icon.png: useful for portable folders or pages opened under a known directory.
  • Absolute https://cdn.example.com/icon.png: useful for a stable public CDN, with extra host and access-control checks.

Two advanced cases change resolution:

  • A document <base href="..."> affects relative URL resolution, including root-relative URLs when the base points to another origin.
  • A site deployed under /project/ may not serve anything at the host-root /favicons/; its correct public path could be /project/favicons/.

Use the URL constructor mental model: resolve the literal href against the page's effective base URL, then test that absolute result.

Understand every HTML attribute

rel

rel="icon" identifies a browser icon candidate. rel="apple-touch-icon" is Apple's separate home-screen convention. rel="manifest" points to installed-app metadata.

href

This is a URL, not a filesystem path. Backslashes, repository paths, and C:\... do not belong here.

type

This is a hint describing the image media type. Common values include image/png and image/svg+xml. ICO responses are commonly served as image/x-icon or image/vnd.microsoft.icon; omitting type on the ICO fallback avoids making an incorrect claim.

sizes

For raster images, use intrinsic dimensions such as 32x32. For a scalable icon, sizes="any" tells the user agent it can scale. This attribute does not resize or validate the underlying file.

media

Browsers can choose icons based on a media query. A light/dark SVG pair can be declared like this:

<link
  rel="icon"
  href="/favicons/icon-light.svg"
  type="image/svg+xml"
  media="(prefers-color-scheme: light)"
/>
<link
  rel="icon"
  href="/favicons/icon-dark.svg"
  type="image/svg+xml"
  media="(prefers-color-scheme: dark)"
/>

Keep a conventional fallback and test target browsers. The HTML selection model allows the browser to consider type, media, and sizes; when candidates are equally appropriate, the HTML standard defines how later links participate in selection.

crossorigin

Do not add it reflexively. MDN notes that Chromium does not use crossorigin for rel="icon" as developers may expect. A same-origin icon avoids unnecessary cross-origin complexity.

Configure the server response

Correct markup can still fail when the asset pipeline lies about the file.

Status and body

Each icon should return a successful response whose body is the actual image. Watch for:

  • 404 Not Found from an omitted build artifact
  • 403 Forbidden from hotlink or bot protection
  • 200 text/html from an SPA fallback or login page
  • A redirect loop between www and apex hosts
  • 500 because an image optimizer tries to process ICO

MIME types

Typical mappings:

.png       image/png
.svg       image/svg+xml
.ico       image/x-icon or image/vnd.microsoft.icon
.webmanifest application/manifest+json

If a static server does not know .webmanifest, configure the type explicitly or use a valid JSON response type and test actual target browsers.

Caching

Icons are cached aggressively across browsers, service workers, proxies, and CDNs. There are two sound strategies:

  1. Use versioned filenames with long immutable caching, then update declarations during a redesign.
  2. Keep a stable URL with a shorter or revalidating policy, purge it deliberately, and preserve that stable location for Google Search.

For a search-facing icon, Google asks for a stable URL. Do not generate a new hashed filename on every unrelated deploy. Inspect cache-control, etag, last-modified, vendor cache headers, and actual bytes before blaming the browser.

Content Security Policy

A restrictive policy or extension can block image loads. Open the Console and look for a CSP violation. Ensure the icon's origin is allowed by the site's relevant image policy, especially when the file lives on a CDN.

Verify everything after deployment

Automated scan

Run the final page through the Favicon Checker. It discovers declared browser and Apple icons, resolves URLs, fetches them, and reports common omissions. It does not replace manifest, device, or Search testing.

Direct command-line checks

curl -Ls https://example.com/ | grep -iE 'rel=["'"'](icon|apple-touch-icon|manifest)'
curl -sS -L -D - -o /tmp/favicon.ico https://example.com/favicons/favicon.ico
file /tmp/favicon.ico
curl -sS https://example.com/favicons/site.webmanifest

If curl -I fails, repeat with GET as shown. Some servers implement the methods differently.

Browser checks

  1. Open DevTools Network and enable Disable cache.
  2. Reload and filter for icon and manifest requests.
  3. Inspect final URLs, status, content type, and response preview.
  4. Check the rendered <head> for duplicates.
  5. Test a private profile and another browser.
  6. Save to an iOS home screen when Apple coverage matters.
  7. Install the PWA when manifest coverage matters.

Google Search checks

Google needs the icon declaration on the hostname's homepage, a square crawlable file, and time to reprocess it. A browser tab updating immediately does not mean Search will. Use the full Google Search icon troubleshooting guide.

Common mistakes and fixes

SymptomCauseFix
Works on /, fails on nested pagesPath-relative href resolves inside each route.Use the correct root or deployment-base path.
Icon URL displays the appCatch-all route returns HTML.Exclude static assets from the fallback.
Works locally, 404s in productionFile was not copied into published output.Inspect build artifact and deploy root.
Browser shows an old logoCache, service worker, or CDN still has old bytes.Compare direct response, purge deliberately, update cache version.
Apple shortcut uses a screenshotTouch icon is absent or invalid.Add and test a 180x180 Apple icon.
Installed icon is croppedStandard artwork ignored maskable safe zone.Export a separate maskable asset and declare its purpose.
Search shows a globeHomepage/image is not eligible or not reprocessed.Check Google requirements and request homepage recrawl.
SVG looks blankMissing square viewBox, CSS dependency, or poor contrast.Make the SVG self-contained and preview small.
Duplicate network requestsSeveral metadata systems declare competing candidates.Remove obsolete tags and keep one deliberate set.

Release checklist

  • Source artwork is square, simple, and legible at 16px.
  • Every asset exists in the published output.
  • href values resolve on / and nested routes.
  • The shared <head> contains one intentional set of declarations.
  • Raster sizes match intrinsic dimensions.
  • Direct GET requests return images, not HTML.
  • Content types match the files.
  • The manifest is valid JSON and every src works.
  • Apple and maskable assets have been tested on relevant devices.
  • Cache and CDN headers match the update strategy.
  • No CSP, WAF, or authentication rule blocks public assets.
  • The production hostname passes automated and manual checks.

Frequently asked questions

Can I use only favicon.ico?

Yes for basic browser coverage. Add modern PNG or SVG, Apple, and manifest assets when those surfaces matter. A multi-size ICO is still a useful fallback.

Does the favicon have to be in the root directory?

No. It can live in /favicons/, on a deployment base path, or at an absolute CDN URL. The declaration must point to the exact public location. Root /favicon.ico remains a helpful conventional fallback.

Both belong in <head> and their relative order is rarely the problem. Ordering matters when several icon candidates are equally appropriate, so keep candidate declarations grouped and intentional.

Can I use JPG?

Some user agents support it, but JPG has no transparency and is a poor default for tiny graphic marks. PNG, ICO, and SVG cover common favicon needs more predictably.

Why not base64-encode the icon in the HTML?

Data URLs can work in selected browsers but are awkward for external crawlers, caching, inspection, and cross-platform reuse. A stable public asset URL is easier to verify.

Do I need browserconfig.xml?

Most current browser installations do not depend on it. Keep it only when a historical Microsoft pinned-tile target is part of your compatibility requirements; otherwise it is optional.

How do I change an icon without confusing caches?

Verify new bytes at the origin, purge the CDN, update any service-worker cache, and test a clean profile. Use a deliberate filename transition for a rebrand, then settle on a stable final URL rather than rotating it continuously.

Primary references

The durable installation is the one you can explain: a small set of purpose-built files, explicit public URLs, valid image responses, and tests on the real surfaces your visitors use.

Put this guide into practice

Build a complete favicon pack, then test the live result before you ship.

Written by

FaviconMaker Editorial Team

Practical favicon guidance for designers, developers, and site owners, with a focus on files you can verify in production.

Follow new guides via RSS

Worth sharing?

Send this guide to someone fixing their site icon.

Keep learning

wix3 min

How to Change Favicon on Wix

Step-by-step: change your Wix favicon from the dashboard Settings, understand Premium + domain requirements, choose the right file format/size, and troubleshoot caching and Google display.

Read guide
shopify4 min

How to Change Favicon on Shopify

Step-by-step: change your Shopify store favicon via Theme settings, pick the right 16×16/32×32 image, understand plan limitations, and fix common caching and Google display issues.

Read guide
wordpress4 min

How to Change Favicon in WordPress

Step-by-step: set (or change) your WordPress Site Icon / favicon in WordPress 6.5+ and older versions, choose the right image size, and troubleshoot caching and Google search display.

Read guide