ScreenshotNeo

BlogHow-to

How to Change a Favicon in HTML

Add, replace, and troubleshoot favicons in HTML, including PNG, ICO, SVG, Apple home-screen, and PWA icons.

By the ScreenshotNeo team1 October 20267 min read

To change a favicon in HTML, place the icon file on your deployed site and reference it from the document’s <head>:

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

For an ICO file, use:

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

The rel="icon" link identifies the page icon. The href must resolve to an image URL that works after deployment. The type and sizes attributes are optional hints that help browsers choose between multiple files. See the MDN <link> reference and its icon relation documentation.

Put the declaration alongside your title and other metadata, before the closing </head> tag:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Example site</title>
  <link rel="icon" type="image/png" href="/assets/favicon.png">
</head>
<body>
  <h1>Example site</h1>
</body>
</html>

A root-relative path such as /assets/favicon.png starts at the site root. A document-relative path such as images/favicon.png is resolved relative to the current page URL, which can break on nested routes. Use the path that matches where the file is actually deployed.

2. Choose an icon format and size

ICO

ICO is a conventional choice and often contains several raster sizes in one file:

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

PNG

PNG is straightforward and works well when you provide explicit dimensions:

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

SVG

SVG is useful for a scalable mark when the browser supports the supplied MIME type:

<link rel="icon" type="image/svg+xml" href="/favicon.svg">

If you provide alternatives, include one link per file and make each sizes value match the image’s real dimensions:

<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">

Browsers can use the media, type, and sizes attributes when selecting among multiple icon links. Supplying several accurate options is clearer than relying on one oversized file.

3. Use the right path strategy

  • Root-relative: /favicon.png or /assets/favicon.svg. This usually works consistently across routes.
  • Document-relative: favicon.png. This is resolved against the current document URL and must be correct for every route where the head is rendered.
  • Absolute URL: https://cdn.example.com/favicon.png. Use this only when the asset is intentionally hosted on another origin and is publicly reachable.

The URL in href is the deployed resource location, not the filename in your local source tree. Open that URL directly in a browser or request it with a command-line HTTP client to confirm it exists.

4. Support Apple home-screen icons and PWAs

A browser-tab favicon is separate from an Apple home-screen icon. For a site-wide Apple icon, Apple documents a root PNG named apple-touch-icon.png; you can also declare it explicitly:

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

For a progressive web app, link a manifest separately:

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

Example manifest:

{
  "name": "Example site",
  "short_name": "Example",
  "start_url": "/",
  "display": "standalone",
  "icons": [
    {
      "src": "/icons/icon-192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/icons/icon-512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "/icons/icon.svg",
      "sizes": "any",
      "type": "image/svg+xml"
    }
  ]
}

Manifest icon paths resolve relative to the manifest URL. Raster entries should state their actual dimensions; SVG entries can use sizes: "any". A PWA app icon is not the same asset as the favicon shown in browser UI, as explained by MDN’s manifest icon documentation.

5. Understand the /favicon.ico convention

Browsers may request /favicon.ico automatically when no explicit icon link is present. Keeping that file at the site root can provide a fallback, but an explicit <link rel="icon"> declaration documents your choice and lets you select another format or path. Do not assume the convention points to the file you intended.

6. Verify a favicon after deployment

  1. Open the final deployed HTML and confirm the link is inside <head>.
  2. Copy the href URL and open it directly.
  3. Confirm the response contains the intended image and that the supplied MIME type matches the file.
  4. If several icons exist, check every sizes value against the actual dimensions.
  5. Inspect a private window or a fresh browser profile if the old icon remains visible. Browsers cache favicons independently of ordinary page content.
  6. Check the page at the real route where the problem occurs; a relative path can work on / and fail on /docs/page.

To preview a deployed page at multiple viewport sizes and confirm that the updated head is served by production, you can capture it with ScreenshotNeo.

7. Troubleshooting common favicon problems

Symptom Likely cause Fix
No icon appears The link is outside <head>, the file URL is wrong, or the file is not deployed. Move the link into <head>, open the exact href URL, and inspect the deployed HTML.
The old icon remains Favicon caching. Reload in a private window or fresh profile, then verify the network request and deployed file.
Works on the home page but not nested routes A document-relative path resolves to the wrong directory. Use a root-relative path such as /assets/favicon.png.
Browser rejects the file The declared type does not match the response MIME type or file format. Correct the server MIME type or remove an incorrect type hint.
Only one of several icons is used Incorrect sizes, unsupported format, or competing declarations. Match dimensions exactly, provide supported formats, and remove stale duplicate links.
Apple home-screen icon is missing Only a browser favicon was configured. Add rel="apple-touch-icon" and deploy the PNG at the referenced URL.
PWA install uses the wrong image The manifest is missing, inaccessible, or its icon paths are wrong. Validate the manifest URL and resolve each src relative to the manifest location.
Icon is blurry A small raster is being scaled up. Provide correctly sized raster alternatives or an SVG where supported.

8. Performance, reliability, and maintenance

  • Keep favicon files small; they are requested early and do not need photographic detail.
  • Use immutable, content-hashed filenames when your deployment pipeline supports them, then update the HTML reference with each new asset.
  • Keep a stable root fallback such as /favicon.ico if third-party tools or older clients expect it.
  • Set accurate cache headers, but remember that browsers can retain favicons longer than normal page assets.
  • Test production paths after changes to a CDN, reverse proxy, service worker, or framework base path.
  • Do not place confidential data in an icon URL; it can be requested by browsers and crawlers.

Or skip the browser setup

If your goal is to inspect the deployed page visually after changing its favicon, ScreenshotNeo returns a screenshot or PDF from one GET request. It removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. See the ScreenshotNeo API documentation.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Create a free ScreenshotNeo account with 1,000 screenshots each month and no card required.

FAQ

Do I need both PNG and ICO?

No. One supported, correctly served icon is enough. Multiple formats are useful when you want broader fallback coverage or different dimensions.

No specific order is required. Keep it inside <head> with the rest of the page metadata.

Can CSS change a favicon?

No. Favicons are declared with HTML link elements or supplied through a web app manifest for installation contexts.

Why does the tab update later than the HTML?

Browsers cache favicons separately and may reuse an older resource. Verify the deployed URL and inspect it from a private window or fresh profile.

Is an Apple touch icon the same as a PWA icon?

No. They serve different installation contexts and use separate declarations.