# Hyperflow Favicon

Dynamically generates multi-resolution ICO favicons for Webflow sites by extracting and composing icon images from the site's homepage.&#x20;

{% hint style="warning" %}
**STATUS: TESTING** \
Currently in SEO testing on Sygnal's site.  &#x20;

<https://www.sygnal.com/favicon.ico>&#x20;
{% endhint %}

### Features&#x20;

#### Smart Icon Detection

* Automatically fetches the homepage and extracts icon links
* Supports multiple icon types:
  * `<link rel="shortcut icon">`
  * `<link rel="icon">`
  * `<link rel="apple-touch-icon">`
* Resolves relative and absolute URLs correctly

#### Multi-Format Support

* **Primary**: PNG images (most common in Webflow)
* **ICO extraction**: Can extract PNG data from existing ICO files
* **Graceful degradation**: Skips unsupported formats (GIF, JPG) that require transcoding

#### ICO Composition

* Builds valid multi-resolution ICO files from multiple PNG sources
* Embeds PNGs directly without transcoding (efficient and fast)
* Sorts icons by size for optimal browser compatibility
* Supports icons up to 256×256 pixels

#### Performance & Caching

* **Edge caching**: Returns cached ICO files instantly for repeat requests
* **7-day cache**: `Cache-Control: public, max-age=604800, immutable`
* **Upstream caching**: Caches homepage and icon fetches at Cloudflare edge
* Zero dependencies, optimized for Cloudflare Workers runtime

#### Error Handling

* Gracefully handles missing or invalid icons
* Continues processing if individual icon fetches fail
* Returns appropriate HTTP status codes (404, 502, 500)

### How It Works

1. **Request**: Browser requests `/favicon.ico` from your domain
2. **Fetch**: Worker fetches the homepage (`/`) from the same origin
3. **Parse**: Extracts icon URLs from `<link>` tags in the HTML
4. **Download**: Fetches each icon image (with edge caching)
5. **Process**: Reads PNG dimensions and validates format
6. **Compose**: Builds a multi-resolution ICO file containing all valid PNGs
7. **Cache & Serve**: Returns the ICO with aggressive caching headers

### Usage

Once deployed, the worker will automatically respond to `/favicon.ico` requests:

```
https://your-domain.com/favicon.ico
```

All other paths return a 404 response.

### Configuration

The worker requires no configuration. It automatically:

* Detects the request origin
* Fetches the homepage from the same origin
* Extracts and processes icons
* Caches results at the edge

### Technical Details

#### Icon Extraction

Uses regex-based HTML parsing to find icon `<link>` tags:

```regex
/<link[^>]*rel=["'](?:shortcut\s+icon|icon|apple-touch-icon)["'][^>]*>/gi
```

#### PNG Format Detection

Validates PNG files by checking the 8-byte signature:

```
89 50 4E 47 0D 0A 1A 0A
```

#### ICO File Structure

Generates valid ICO files with:

* ICONDIR header (6 bytes)
* ICONDIRENTRY for each image (16 bytes each)
* PNG image data (embedded without transcoding)

#### Size Handling

* Icons ≥256px are encoded as `0` in ICO directory (per ICO spec)
* Smaller icons use their actual dimensions
* Multiple resolutions are sorted smallest to largest

### Limitations

* **PNG focus**: Webflow typically uses PNG icons. GIF and JPG formats are skipped unless they can be extracted from ICO containers
* **Image transcoding**: No built-in image format conversion (keeps worker lightweight)
* **Same-origin**: Fetches icons from the same domain as the request

### Development

#### Local Testing

```bash
npm run dev
```

Visit `http://localhost:8787/favicon.ico`

#### Type Generation

```bash
npm run cf-typegen
```

#### Deployment

```bash
npm run deploy
```

### Troubleshooting

#### "No icons found" error

* Ensure your Webflow site has `<link rel="icon">` or `<link rel="apple-touch-icon">` tags in the homepage HTML
* Check that the icon URLs are accessible

#### "No valid PNG icons found" error

* Verify that your icons are in PNG format
* Check that icon URLs return valid PNG data
* Ensure icons have valid PNG headers (signature + IHDR chunk)

#### Cache issues

* Edge cache lasts 7 days
* To force refresh, clear Cloudflare cache or wait for TTL expiration
* During development, use `wrangler dev` which bypasses edge cache

## Future&#x20;

* Interpolate
  * 48x48 size in ICO&#x20;
  * 16x16 size in ICO
* SVG icon support ?&#x20;
* Desktop PNG favicon ?&#x20;
* Android chrome favicon not set  \
  Chrome selects the 192x192 icon if it is available and the 128x128 icon if it is not.
* Rel shortcut icon&#x20;

  ```
  <link rel="shortcut icon" href="/path/to/favicon">
  ```
* Consider ref&#x20;

  ```
  <link rel="icon" type="image/x-icon" href="url_to_my_favicon" /> 
  ```

<https://realfavicongenerator.net/favicon-checker>

### PWA & Web manifest&#x20;

<https://web.dev/articles/add-manifest>

|                                      |                           |                   |
| ------------------------------------ | ------------------------- | ----------------- |
| \<link> shortcut icon                | Webflow, 32x32            |                   |
| \<link> icon                         |                           |                   |
| \<link> apple-touch-icon             | Webflow, 256x256          |                   |
| \<link> apple-touch-icon-precomposed |                           |                   |
| /favicon.ico                         |                           | Hyperflow Favicon |
| /manifest.json                       | Webflow internal, not PWA |                   |

<table><thead><tr><th width="109"></th><th></th><th></th></tr></thead><tbody><tr><td>16x16</td><td></td><td></td></tr><tr><td>24x24</td><td></td><td></td></tr><tr><td>32x32</td><td>Use Webflow's uploaded icon, PNG preferred </td><td></td></tr><tr><td>48x48</td><td></td><td></td></tr><tr><td>64x64</td><td></td><td></td></tr><tr><td>128x128</td><td></td><td>Chrome selects the 192x192 icon if it is available and the 128x128 icon if it is not.</td></tr><tr><td>192x192</td><td></td><td>Chrome selects the 192x192 icon if it is available and the 128x128 icon if it is not.</td></tr><tr><td>256x256</td><td>Use Webflow's uploaded icon, PNG preferred </td><td></td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hyperflow.sygnal.com/apps/hyperflow-favicon.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
