favicon.blueat.net#
The fastest way to fetch favicons for any website.
A Cloudflare Worker that fetches a website’s favicon by domain, caches responses at the edge, and returns the image (or a redirect fallback).
Endpoint#
GET https://favicon.blueat.net/{domain}
GET https://favicon.blueat.net/{domain}?larger=true
Parameters#
| Parameter | Default | Description |
|---|---|---|
larger |
false |
Return a high-res icon (128px+). Prefers SVG, then large PNG. |
default-avatar |
— | URL to redirect to when no favicon is found. Must be URL-encoded. |
throw-error-on-404 |
false |
Return HTTP 404 instead of a placeholder when no favicon is found. |
Examples#
HTML#
<!-- Standard 16px favicon -->
<img src="https://favicon.blueat.net/github.com"
width="16" height="16" alt="GitHub" />
<!-- High-resolution (128px+) -->
<img src="https://favicon.blueat.net/github.com?larger=true"
width="64" height="64" alt="GitHub" />
<!-- Custom fallback when no favicon is found -->
<img src="https://favicon.blueat.net/unknown.xyz?default-avatar=https%3A%2F%2Fexample.com%2Fdefault.png"
width="16" height="16" alt="favicon" />
JavaScript#
const res = await fetch("https://favicon.blueat.net/github.com?larger=true");
const blob = await res.blob();
document.getElementById("icon").src = URL.createObjectURL(blob);
How it works#
- Check the Workers cache for this domain (and
largerflag). - If
larger, try Google’s favicon service at 128px. - Otherwise fetch the site HTML and parse
<link rel="icon">/ apple-touch-icon tags. - Fall back to
/favicon.ico, then Google’s 32px favicon. - If nothing works, redirect to a default image or your
default-avatar, or return 404 when requested.
Why might a favicon not be found?#
| Reason | Details |
|---|---|
| Site has no favicon | The domain has no /favicon.ico, no <link rel="icon"> tag, and Google has no cached icon for it. Rare for established sites, common for new or private ones. |
| Site blocks bots | The domain's server returns a 403 or 429 for automated requests, preventing the HTML parse step. The /favicon.ico direct fetch and Google S2 fallbacks are still attempted. |
| Request timeout | Each upstream fetch has a 5 second timeout. Slow or unresponsive origins will be skipped. If all strategies time out, the fallback image is returned. |
| Icon behind authentication | Some sites only serve their favicon to authenticated users, so the HTML fetch returns a login page with no <link> tags pointing to a real icon. |
| Non-standard content type | The worker validates that responses have an image content type (image/*, icon, svg, or octet-stream). Files served with an unexpected content type are rejected. |
| Domain doesn't exist | DNS resolution fails for the domain, so all direct fetch strategies return nothing. Google S2 is still tried as a last resort since Google may have a cached record. |
| Icon is an inline data URI | Some sites embed their icon directly as a data: URL in the <link> tag. These are intentionally skipped — only external URLs are fetched. |
Try it#
| default | https://favicon.blueat.net/BlueAT.net |
| larger=true | https://favicon.blueat.net/BlueAT.net?larger=true |
Development & deploy#
npm install
npm run dev
Open http://localhost:8787/github.com while dev is running.
Deploy:
npx wrangler login # once per machine
npm run deploy
Edit wrangler.toml and set name to the Worker name you want in Cloudflare.
Files#
worker.js— Worker entrypointwrangler.toml— Wrangler project config
License#
Use and modify as you like for your own deployment.