Fashionable Favicons

Fashionable Favicons

How this website fetches favicons statically and automagically.

29.02.2024

Why? ๐Ÿค”

If you have spent more than a minute on this website, you'll know that I like putting icons and emojis in text. ๐Ÿ“ They make everything more fun and serve as a visual aid to quickly identify links and topics. ๐Ÿง 

Now, I could go and manually download and resize every single favicon I want to use, but that would be a lot of work. ๐Ÿ’ฉ Instead, I fetch them dynamically at build time, convert them to .webp and serve them statically.

Look at them go! ๐Ÿš€

Facebook

Favicon
ย  Twitter
Favicon
ย  Instagram
Favicon
ย  LinkedIn
Favicon
ย  GitHub
Favicon
ย  Minecraft
Favicon
ย  Reddit
Favicon
ย  YouTube
Favicon
ย  Spotify
Favicon
ย  Discord
Favicon
ย  Twitch
Favicon
ย  WhatsApp
Favicon
ย  Slack
Favicon
ย  Google
Favicon
ย  Apple
Favicon
ย  xkcd
Favicon

The easy way ๐Ÿฅฒ

Having favicons show up next to links could be soo easy:

<a href="https://kosro.de">
  Click me
  <img src="http://www.google.com/s2/favicons?domain=kosro.de" />
</a>

This works thanks to Google's internal favicon API. There's also some other services that offer this, like DuckDuckGo and Yandex:

https://www.google.com/s2/favicons?domain=kosro.de?sz=64

https://icons.duckduckgo.com/ip2/kosro.de.ico

https://favicon.yandex.net/favicon/v2/kosro.de/reddit.com

Keep in mind that these services are not officially documented and could be taken down at any time.

GDPR Compliance ๐Ÿ‡ช๐Ÿ‡บ

The GDPR

Favicon
basically (and rightly ๐Ÿ˜ˆ) regards the USA as a third world country, thanks to it's horrid privacy laws.

As IP addresses are considered personal data, explicit consent is required before any requests may be made to a server in the USA.

This means that directly using most favicon APIs is a no-go for any website that wants to be GDPR compliant. Shucks. ๐Ÿ’ฉ

The hard way ๐Ÿชจ

Luckily, Nuxt Image

Favicon
has a solution for this. It's a module that allows you to fetch images statically at build time. This means that the images are already on the server when the user requests the page, and no further external requests are made.

Awesome! So I can just use the Google API and be done with it, right?

Nope.

Turns out, Nuxt Image

Favicon
and IPX
Favicon
completely shit themselves as soon as there's query parameters in the image URL.

WHICH IS MENTIONED EXACTLY 0 TIMES IN THE DOCS ๐Ÿคฌ

At least there's this issue

Favicon
...

Unfortunately, most favicon APIs require query parameters to pass the URL or desired size. DuckDuckGo

Favicon
does not, but it returns some icons in .ico format, which IPX
Favicon
can't handle. This is why I had to resort to fetching favicons from Yandex
Favicon
.

Making it pretty โœจ

So far so good. Next problem:

Some icons are black. The website's background is black.

Enter fast-average-color

Favicon
, a module capable of extracting the average color of an image element, efficiently and client side.

I register a callback for when the icon is loaded (or mounted in case of prerendered pages

Favicon
), get it's average color and calculate the saturation. If both brightness and saturation are low, I invert the icon's colors.

And that's it!