The Cloudflare Worker code behind favicon.blueat.net favicon.blueat.net
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

updated readme

+72 -26
+72 -26
README.md
··· 1 1 # favicon.blueat.net 2 2 3 - A small [Cloudflare Worker](https://developers.cloudflare.com/workers/) that fetches a website’s favicon by domain, caches responses at the edge, and returns the image (or a redirect fallback). 3 + The fastest way to fetch favicons for any website. 4 + 5 + A [Cloudflare Worker](https://developers.cloudflare.com/workers/) that fetches a website’s favicon by domain, caches responses at the edge, and returns the image (or a redirect fallback). 4 6 5 - ## Quick start 7 + ## Endpoint 6 8 7 - ```bash 8 - npm install 9 - npm run dev 9 + ``` 10 + GET https://favicon.blueat.net/{domain} 11 + GET https://favicon.blueat.net/{domain}?larger=true 10 12 ``` 11 13 12 - Open `http://localhost:8787/example.com` while `dev` is running. 14 + ## Parameters 13 15 14 - Deploy: 16 + | Parameter | Default | Description | 17 + |-----------|---------|-------------| 18 + | `larger` | `false` | Return a high-res icon (128px+). Prefers SVG, then large PNG. | 19 + | `default-avatar` | — | URL to redirect to when no favicon is found. Must be URL-encoded. | 20 + | `throw-error-on-404` | `false` | Return HTTP 404 instead of a placeholder when no favicon is found. | 15 21 16 - ```bash 17 - npx wrangler login # once per machine 18 - npm run deploy 19 - ``` 22 + ## Examples 20 23 21 - Edit `wrangler.toml` and set `name` to the Worker name you want in Cloudflare. 22 - 23 - ## Usage 24 + ### HTML 24 25 25 - Request path is the domain (no protocol): 26 + ```html 27 + <!-- Standard 16px favicon --> 28 + <img src="https://favicon.blueat.net/github.com" 29 + width="16" height="16" alt="GitHub" /> 26 30 27 - | URL | Meaning | 28 - |-----|--------| 29 - | `/{domain}` | Resolve favicon for `domain` | 31 + <!-- High-resolution (128px+) --> 32 + <img src="https://favicon.blueat.net/github.com?larger=true" 33 + width="64" height="64" alt="GitHub" /> 30 34 31 - **Query parameters** 35 + <!-- Custom fallback when no favicon is found --> 36 + <img src="https://favicon.blueat.net/unknown.xyz?default-avatar=https%3A%2F%2Fexample.com%2Fdefault.png" 37 + width="16" height="16" alt="favicon" /> 38 + ``` 32 39 33 - | Param | Effect | 34 - |--------|--------| 35 - | `larger=true` | Prefer larger icons (e.g. Google s2 at 128px, SVG, or big apple-touch sizes from HTML) | 36 - | `default-avatar=<url>` | If no favicon is found, `302` redirect to this URL | 37 - | `throw-error-on-404=true` | If no favicon is found, return `404` instead of redirecting | 40 + ### JavaScript 38 41 39 - Successful responses include `Cache-Control`, `Access-Control-Allow-Origin: *`, and `X-Favicon-Source` describing where the icon came from. 42 + ```javascript 43 + const res = await fetch("https://favicon.blueat.net/github.com?larger=true"); 44 + const blob = await res.blob(); 45 + document.getElementById("icon").src = URL.createObjectURL(blob); 46 + ``` 40 47 41 48 ## How it works 42 49 ··· 44 51 2. If `larger`, try Google’s favicon service at 128px. 45 52 3. Otherwise fetch the site HTML and parse `<link rel="icon">` / apple-touch-icon tags. 46 53 4. Fall back to `/favicon.ico`, then Google’s 32px favicon. 47 - 5. If nothing works, redirect to a default image or your `default-avatar`, or `404` when requested. 54 + 5. If nothing works, redirect to a default image or your `default-avatar`, or return 404 when requested. 55 + 56 + ### Why might a favicon not be found? 57 + 58 + | Reason | Details | 59 + |--------|---------| 60 + | 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. | 61 + | 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. | 62 + | 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. | 63 + | 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. | 64 + | 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. | 65 + | 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. | 66 + | 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. | 67 + 68 + ## Try it 69 + 70 + | | | 71 + |--|--| 72 + | default | [https://favicon.blueat.net/BlueAT.net](https://favicon.blueat.net/BlueAT.net) | 73 + | larger=true | [https://favicon.blueat.net/BlueAT.net?larger=true](https://favicon.blueat.net/BlueAT.net?larger=true) | 74 + 75 + --- 76 + 77 + ## Development & deploy 78 + 79 + ```bash 80 + npm install 81 + npm run dev 82 + ``` 83 + 84 + Open `http://localhost:8787/github.com` while `dev` is running. 85 + 86 + Deploy: 87 + 88 + ```bash 89 + npx wrangler login # once per machine 90 + npm run deploy 91 + ``` 92 + 93 + Edit `wrangler.toml` and set `name` to the Worker name you want in Cloudflare. 48 94 49 95 ## Files 50 96