FindSiteIcon
Find a usable, high-quality icon for a website URL.
FindSiteIcon fetches a page, extracts known icon links, adds common fallback locations, probes the candidates, and returns the best icon URL it can validate. It is built on Req and keeps the public API small enough to use directly in application code.
Installation
Add find_site_icon to your dependencies:
def deps do
[
{:find_site_icon, "~> 1.0"}
]
endQuick Start
case FindSiteIcon.find_icon("https://nytimes.com") do
{:ok, icon_url} ->
icon_url
{:error, reason} ->
reason
endIf you already have the page HTML, pass it in to avoid an extra fetch:
FindSiteIcon.find_icon("https://example.com/article", html: html)For hot paths, cap the whole lookup:
FindSiteIcon.find_icon("https://example.com", timeout: 3_000)Options
| Option | What it does |
|---|---|
:html | Uses caller-provided HTML instead of fetching the page first. |
:default_icon_url | Returns {:ok, default_icon_url} when no valid icon is found. |
:timeout | Caps the whole lookup and applies the same timeout to internal HTTP requests. |
:http_options | Passes Req options to the internal HTTP client. |
:max_concurrency | Limits concurrent icon probes. Defaults to 8. |
:max_icons | Limits how many candidate icon URLs are probed. Defaults to 20. |
What It Checks
- HTML icon links:
apple-touch-icon,apple-touch-icon-precomposed,shortcut icon, andicon. - Common fallback locations such as
/apple-touch-icon.pngand/favicon.png. - PNG, JPEG, WebP, and SVG icon URLs.
- Response metadata with a HEAD-first request, falling back to GET when needed.
cache-control: max-agefor cache expiration when the server provides it.
Development
mix deps.get
mix test
mix credo --strict
mix dialyzer
The live website smoke test is tagged :external so regular test runs do not depend on the public internet:
mix test --include external
Documentation is available at hexdocs.pm/find_site_icon.