Hoe maak je adaptieve favicons voor lichte en donkere modus: Complete ontwikkelaarshandleiding

Favicon.im

Moderne websites moeten zich aanpassen aan gebruikersvoorkeuren, en favicon-theming is een vaak over het hoofd gezien detail dat de gebruikerservaring aanzienlijk kan verbeteren. Wanneer gebruikers wisselen tussen lichte en donkere modus, moet je favicon zich dienovereenkomstig aanpassen om visuele consistentie te behouden.

Deze uitgebreide handleiding behandelt alles van eenvoudige HTML-only oplossingen tot geavanceerde JavaScript-implementaties in populaire frameworks. Of je nu een statische site of een complexe webapplicatie bouwt, je vindt hier de juiste aanpak voor je project.

Methode 1: HTML-only oplossing (Aanbevolen voor de meeste sites)

De HTML-only aanpak is de meest betrouwbare methode en vereist geen JavaScript. Het gebruikt CSS media queries binnen het media-attribuut van favicon link-tags om automatisch favicons te wisselen op basis van de systeemvoorkeur van de gebruiker.

Waarom deze methode het beste werkt:

  • Nul JavaScript vereist
  • Werkt direct bij het laden van de pagina
  • Ondersteund door alle moderne browsers
  • Geen prestatie-overhead

Basisimplementatie

<head>
  <!-- Standaard favicon (fallback voor niet-ondersteunde browsers) -->
  <link rel="icon" href="/favicon-light.ico" type="image/x-icon">

  <!-- Lichte modus-favicon -->
  <link rel="icon" href="/favicon-light.ico" type="image/x-icon" media="(prefers-color-scheme: light)">

  <!-- Donkere modus-favicon -->
  <link rel="icon" href="/favicon-dark.ico" type="image/x-icon" media="(prefers-color-scheme: dark)">
</head>

Volledige multi-maat implementatie

Voor uitgebreide apparaatondersteuning, implementeer meerdere maten met thema-varianten:

<head>
  <!-- Standaard favicons (fallback) -->
  <link rel="icon" type="image/x-icon" href="/favicon-light.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-light-32x32.png">

  <!-- Lichte modus-favicons -->
  <link rel="icon" type="image/x-icon" href="/favicon-light.ico" media="(prefers-color-scheme: light)">
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-light-16x16.png" media="(prefers-color-scheme: light)">
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-light-32x32.png" media="(prefers-color-scheme: light)">
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-light.png" media="(prefers-color-scheme: light)">

  <!-- Donkere modus-favicons -->
  <link rel="icon" type="image/x-icon" href="/favicon-dark.ico" media="(prefers-color-scheme: dark)">
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-dark-16x16.png" media="(prefers-color-scheme: dark)">
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-dark-32x32.png" media="(prefers-color-scheme: dark)">
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-dark.png" media="(prefers-color-scheme: dark)">

  <!-- SVG-favicons met ingebedde CSS -->
  <link rel="icon" type="image/svg+xml" href="/favicon-adaptive.svg">
</head>

Adaptieve SVG-favicon

Maak een enkele SVG-favicon die zich automatisch aanpast aan het kleurenschema:

<!-- favicon-adaptive.svg -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  <style>
    .light-mode { fill: #000000; }
    .dark-mode { fill: #ffffff; }

    @media (prefers-color-scheme: dark) {
      .light-mode { display: none; }
    }

    @media (prefers-color-scheme: light) {
      .dark-mode { display: none; }
    }
  </style>

  <!-- Lichte modus-ontwerp -->
  <circle class="light-mode" cx="16" cy="16" r="12"/>
  <text class="light-mode" x="16" y="20" text-anchor="middle" fill="#fff" font-size="14">L</text>

  <!-- Donkere modus-ontwerp -->
  <circle class="dark-mode" cx="16" cy="16" r="12"/>
  <text class="dark-mode" x="16" y="20" text-anchor="middle" fill="#000" font-size="14">D</text>
</svg>

Methode 2: JavaScript-implementatie

Wanneer je dynamisch favicon wisselen nodig hebt voorbij systeemvoorkeuren — zoals aangepaste thema-schakelaars of realtime updates — biedt JavaScript de flexibiliteit die je nodig hebt.

Gebruik JavaScript wanneer:

  • Je aangepaste themabesturingen hebt
  • Je wilt synchroniseren met de themastatus van je app
  • Je favicons wilt bijwerken zonder paginaverversing
  • Je een single-page applicatie bouwt

Basis JavaScript-aanpak

// Functie om favicon bij te werken op basis van thema
function updateFavicon(theme) {
  const favicon = document.querySelector('link[rel="icon"]') ||
                 document.createElement('link');

  favicon.rel = 'icon';
  favicon.type = 'image/png';
  favicon.href = theme === 'dark' ? '/favicon-dark.png' : '/favicon-light.png';

  if (!document.querySelector('link[rel="icon"]')) {
    document.head.appendChild(favicon);
  }
}

// Luister naar systeemthemawijzigingen
if (window.matchMedia) {
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

  // Stel initieel favicon in
  updateFavicon(mediaQuery.matches ? 'dark' : 'light');

  // Luister naar wijzigingen
  mediaQuery.addEventListener('change', (e) => {
    updateFavicon(e.matches ? 'dark' : 'light');
  });
}

Geavanceerde JavaScript met meerdere maten

class FaviconManager {
  constructor() {
    this.sizes = [
      { size: '16x16', selector: 'link[rel="icon"][sizes="16x16"]' },
      { size: '32x32', selector: 'link[rel="icon"][sizes="32x32"]' },
      { size: '180x180', selector: 'link[rel="apple-touch-icon"]' }
    ];

    this.init();
  }

  init() {
    // Stel initieel thema in
    this.updateTheme(this.getSystemTheme());

    // Luister naar systeemwijzigingen
    if (window.matchMedia) {
      const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
      mediaQuery.addEventListener('change', (e) => {
        this.updateTheme(e.matches ? 'dark' : 'light');
      });
    }
  }

  getSystemTheme() {
    return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
      ? 'dark' : 'light';
  }

  updateTheme(theme) {
    this.sizes.forEach(({ size, selector }) => {
      let link = document.querySelector(selector);

      if (!link) {
        link = document.createElement('link');
        link.rel = size === '180x180' ? 'apple-touch-icon' : 'icon';
        link.type = 'image/png';
        if (size !== '180x180') link.sizes = size;
        document.head.appendChild(link);
      }

      link.href = `/favicon-${theme}-${size}.png`;
    });

    // Update standaard ico-bestand
    let icoLink = document.querySelector('link[rel="icon"][type="image/x-icon"]');
    if (!icoLink) {
      icoLink = document.createElement('link');
      icoLink.rel = 'icon';
      icoLink.type = 'image/x-icon';
      document.head.appendChild(icoLink);
    }
    icoLink.href = `/favicon-${theme}.ico`;
  }

  // Methode om handmatig thema in te stellen (voor aangepaste thema-schakelaars)
  setTheme(theme) {
    this.updateTheme(theme);
  }
}

// Initialiseren
const faviconManager = new FaviconManager();

// Exporteren voor handmatig thema wisselen
window.faviconManager = faviconManager;

Methode 3: Framework-integratie

Moderne frameworks bieden elegante manieren om favicon-theming af te handelen. Zo implementeer je adaptieve favicons in de meest populaire JavaScript-frameworks.

React-implementatie

import { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';

function AdaptiveFavicon() {
  const [theme, setTheme] = useState('light');

  useEffect(() => {
    // Controleer systeemvoorkeur
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    setTheme(mediaQuery.matches ? 'dark' : 'light');

    // Luister naar wijzigingen
    const handleChange = (e) => {
      setTheme(e.matches ? 'dark' : 'light');
    };

    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);

  return (
    <Helmet>
      <link rel="icon" type="image/x-icon" href={`/favicon-${theme}.ico`} />
      <link rel="icon" type="image/png" sizes="32x32" href={`/favicon-${theme}-32x32.png`} />
      <link rel="apple-touch-icon" sizes="180x180" href={`/apple-touch-icon-${theme}.png`} />
    </Helmet>
  );
}

Vue 3-implementatie

<template>
  <div>
    <!-- Je app-content -->
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { useHead } from '@unhead/vue'

const isDark = ref(false)

const updateFavicon = () => {
  const theme = isDark.value ? 'dark' : 'light'

  useHead({
    link: [
      { rel: 'icon', type: 'image/x-icon', href: `/favicon-${theme}.ico` },
      { rel: 'icon', type: 'image/png', sizes: '32x32', href: `/favicon-${theme}-32x32.png` },
      { rel: 'apple-touch-icon', sizes: '180x180', href: `/apple-touch-icon-${theme}.png` }
    ]
  })
}

onMounted(() => {
  // Controleer systeemvoorkeur
  if (window.matchMedia) {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
    isDark.value = mediaQuery.matches

    // Luister naar wijzigingen
    mediaQuery.addEventListener('change', (e) => {
      isDark.value = e.matches
    })
  }

  updateFavicon()
})

watch(isDark, updateFavicon)
</script>

Nuxt 3-implementatie

// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          innerHTML: `
            (function() {
              const updateFavicon = (isDark) => {
                const theme = isDark ? 'dark' : 'light';
                const links = [
                  { rel: 'icon', type: 'image/x-icon', href: \`/favicon-\${theme}.ico\` },
                  { rel: 'icon', type: 'image/png', sizes: '32x32', href: \`/favicon-\${theme}-32x32.png\` }
                ];

                links.forEach(linkData => {
                  let link = document.querySelector(\`link[rel="\${linkData.rel}"][sizes="\${linkData.sizes || 'any'}"]\`);
                  if (!link) {
                    link = document.createElement('link');
                    Object.assign(link, linkData);
                    document.head.appendChild(link);
                  } else {
                    link.href = linkData.href;
                  }
                });
              };

              if (window.matchMedia) {
                const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
                updateFavicon(mediaQuery.matches);
                mediaQuery.addEventListener('change', e => updateFavicon(e.matches));
              }
            })();
          `
        }
      ]
    }
  }
})

Methode 4: CSS-in-JS favicon (Geavanceerd)

Genereer favicons dynamisch met Canvas en CSS-kleuren:

class DynamicFaviconGenerator {
  constructor() {
    this.canvas = document.createElement('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.canvas.width = 32;
    this.canvas.height = 32;
  }

  generateFavicon(theme) {
    const colors = {
      light: { bg: '#ffffff', text: '#000000' },
      dark: { bg: '#000000', text: '#ffffff' }
    };

    const { bg, text } = colors[theme];

    // Wis canvas
    this.ctx.clearRect(0, 0, 32, 32);

    // Teken achtergrond
    this.ctx.fillStyle = bg;
    this.ctx.fillRect(0, 0, 32, 32);

    // Teken rand
    this.ctx.strokeStyle = text;
    this.ctx.lineWidth = 2;
    this.ctx.strokeRect(2, 2, 28, 28);

    // Teken icoon (voorbeeld: letter of symbool)
    this.ctx.fillStyle = text;
    this.ctx.font = 'bold 20px Arial';
    this.ctx.textAlign = 'center';
    this.ctx.textBaseline = 'middle';
    this.ctx.fillText('🌙', 16, 16);

    return this.canvas.toDataURL('image/png');
  }

  updateFavicon(theme) {
    const dataUrl = this.generateFavicon(theme);

    let link = document.querySelector('link[rel="icon"]');
    if (!link) {
      link = document.createElement('link');
      link.rel = 'icon';
      link.type = 'image/png';
      document.head.appendChild(link);
    }

    link.href = dataUrl;
  }
}

// Gebruik
const generator = new DynamicFaviconGenerator();
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

generator.updateFavicon(mediaQuery.matches ? 'dark' : 'light');
mediaQuery.addEventListener('change', e => {
  generator.updateFavicon(e.matches ? 'dark' : 'light');
});

Ontwerp best practices

Het maken van effectieve adaptieve favicons vereist zorgvuldige aandacht voor ontwerpprincipes en gebruikerservaring.

Kleurcontrast en zichtbaarheid

Favicon-ontwerp voor lichte modus:

  • Gebruik donkere elementen (tekst, iconen) op transparante of lichte achtergronden
  • Streef naar WCAG AA-contrastverhoudingen (minimaal 4.5:1)
  • Test het uiterlijk op witte browsertabs en bladwijzerbalken
  • Zorg voor helderheid op 16x16 pixels (kleinste gangbare maat)

Favicon-ontwerp voor donkere modus:

  • Gebruik lichte elementen op transparante of donkere achtergronden
  • Test zichtbaarheid tegen donkere browserthema's
  • Vermijd puur wit (#ffffff) - gebruik gebroken wit (#f0f0f0) voor betere balans
  • Overweeg subtiele schaduwen of contouren voor definitie

Tips voor ontwerpconsistentie

  1. Behoud merkherkenning - Houd je kern-ontwerpelementen consistent
  2. Test op meerdere maten - 16x16, 32x32 en 180x180 pixels
  3. Gebruik eenvoudige vormen - Complexe details verdwijnen op kleine formaten
  4. Houd rekening met kleurenblinde gebruikers - Vertrouw niet alleen op kleur voor differentiatie

Bestandsnaamconventie

Organiseer je faviconbestanden met duidelijke naamgeving:

/public/
├── favicon-light.ico
├── favicon-dark.ico
├── favicon-light-16x16.png
├── favicon-dark-16x16.png
├── favicon-light-32x32.png
├── favicon-dark-32x32.png
├── apple-touch-icon-light.png
├── apple-touch-icon-dark.png
└── favicon-adaptive.svg

Browsercompatibiliteit

Moderne browserondersteuning voor adaptieve favicons

Browser Media query-ondersteuning Opmerkingen
Chrome 76+ Volledige ondersteuning Werkt perfect
Firefox 67+ Volledige ondersteuning Uitstekende implementatie
Safari 12.1+ Volledige ondersteuning Inclusief iOS Safari
Edge 79+ Volledige ondersteuning Chromium-gebaseerde Edge
Internet Explorer Geen ondersteuning Gebruik JavaScript-fallback

Marktdekking: Deze versies dekken ~95% van het wereldwijde browsergebruik in 2025.

Fallback-strategie

<!-- Bied altijd fallbacks -->
<link rel="icon" href="/favicon-light.ico" type="image/x-icon">

<!-- Verbeterde ondersteuning voor moderne browsers -->
<link rel="icon" href="/favicon-light.ico" type="image/x-icon" media="(prefers-color-scheme: light)">
<link rel="icon" href="/favicon-dark.ico" type="image/x-icon" media="(prefers-color-scheme: dark)">

<!-- JavaScript-fallback voor oudere browsers -->
<script>
  if (!window.matchMedia || !CSS.supports('(prefers-color-scheme: dark)')) {
    // Laad favicon op basis van tijdstip of andere heuristieken
    const hour = new Date().getHours();
    const isDark = hour < 6 || hour > 18;
    document.querySelector('link[rel="icon"]').href =
      isDark ? '/favicon-dark.ico' : '/favicon-light.ico';
  }
</script>

Testen en validatie

Handmatige testchecklist

  • [ ] Test in lichte modus (systeemvoorkeur)
  • [ ] Test in donkere modus (systeemvoorkeur)
  • [ ] Controleer of favicon direct verandert bij systeemthema-wisseling
  • [ ] Controleer in verschillende browsers (Chrome, Firefox, Safari, Edge)
  • [ ] Test op mobiele apparaten
  • [ ] Valideer fallback-gedrag in oudere browsers

Geautomatiseerd testen

// Testscript voor favicon-themawisseling
function testFaviconThemes() {
  const tests = [
    { theme: 'light', expected: '/favicon-light.ico' },
    { theme: 'dark', expected: '/favicon-dark.ico' }
  ];

  tests.forEach(({ theme, expected }) => {
    // Mock media query
    Object.defineProperty(window, 'matchMedia', {
      writable: true,
      value: jest.fn().mockImplementation(query => ({
        matches: query.includes('dark') ? theme === 'dark' : theme === 'light',
        addEventListener: jest.fn(),
        removeEventListener: jest.fn(),
      })),
    });

    // Trigger update
    updateFavicon(theme);

    // Assert
    const favicon = document.querySelector('link[rel="icon"]');
    expect(favicon.href).toContain(expected);
  });
}

Prestatieoptimalisatie

Preload thema-favicons

<!-- Preload beide thema-favicons voor directe wisseling -->
<link rel="preload" as="image" href="/favicon-light.ico">
<link rel="preload" as="image" href="/favicon-dark.ico">

Minimaliseer bestandsgrootten

  • Houd ICO-bestanden onder 1KB
  • Optimaliseer PNG-bestanden met tools zoals TinyPNG
  • Gebruik SVG voor eenvoudige geometrische ontwerpen
  • Overweeg WebP-formaat voor moderne browsers

Cachingstrategie

# Nginx-configuratie voor favicon-caching
location ~* \.(ico|png|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    add_header Vary "Accept-Encoding";
}

Probleemoplossing veelvoorkomende problemen

Favicon wisselt niet tussen thema's

Symptomen: Favicon blijft hetzelfde ongeacht systeemthemawijzigingen

Veelvoorkomende oorzaken & oplossingen:

  1. Browsercache-problemen

    <!-- Voeg cache-busting parameters toe -->
    <link rel="icon" href="/favicon-light.ico?v=2025" media="(prefers-color-scheme: light)">
    <link rel="icon" href="/favicon-dark.ico?v=2025" media="(prefers-color-scheme: dark)">
    
  2. Onjuiste media query-syntax

    <!-- Fout -->
    <link rel="icon" href="/favicon-dark.ico" media="dark">
    
    <!-- Correct -->
    <link rel="icon" href="/favicon-dark.ico" media="(prefers-color-scheme: dark)">
    

Meerdere favicons laden tegelijk

Symptomen: Network-tab toont meerdere favicon-verzoeken

Oplossing: Gebruik JavaScript om te vervangen in plaats van toe te voegen:

function replaceFavicon(href) {
  // Verwijder alle bestaande favicon-links
  document.querySelectorAll('link[rel*="icon"]').forEach(link => link.remove());

  // Voeg nieuwe favicon toe
  const link = document.createElement('link');
  link.rel = 'icon';
  link.type = 'image/x-icon';
  link.href = href;
  document.head.appendChild(link);
}

SVG-favicons worden niet weergegeven

Symptomen: SVG-favicon werkt in sommige browsers maar niet in andere

Oorzaak: Beperkte SVG-favicon-ondersteuning in oudere browsers

Oplossing: Bied altijd PNG-fallbacks:

<!-- Moderne browsers: SVG met media queries -->
<link rel="icon" type="image/svg+xml" href="/favicon-adaptive.svg">

<!-- Fallback: PNG voor oudere browsers -->
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-light-32x32.png" media="(prefers-color-scheme: light)">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-dark-32x32.png" media="(prefers-color-scheme: dark)">

Geavanceerde technieken

Themabewuste notificatiebadges

class NotificationFavicon {
  constructor() {
    this.canvas = document.createElement('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.canvas.width = 32;
    this.canvas.height = 32;
    this.baseIcons = {
      light: '/favicon-light-32x32.png',
      dark: '/favicon-dark-32x32.png'
    };
  }

  async drawWithBadge(theme, count) {
    const baseIcon = new Image();
    baseIcon.src = this.baseIcons[theme];

    return new Promise(resolve => {
      baseIcon.onload = () => {
        this.ctx.clearRect(0, 0, 32, 32);
        this.ctx.drawImage(baseIcon, 0, 0, 32, 32);

        if (count > 0) {
          // Teken notificatiebadge
          const badgeSize = 12;
          const x = 32 - badgeSize;
          const y = 0;

          // Badge-achtergrond
          this.ctx.fillStyle = '#ff4444';
          this.ctx.beginPath();
          this.ctx.arc(x + badgeSize/2, y + badgeSize/2, badgeSize/2, 0, 2 * Math.PI);
          this.ctx.fill();

          // Badge-tekst
          this.ctx.fillStyle = 'white';
          this.ctx.font = '8px Arial';
          this.ctx.textAlign = 'center';
          this.ctx.textBaseline = 'middle';
          this.ctx.fillText(
            count > 9 ? '9+' : count.toString(),
            x + badgeSize/2,
            y + badgeSize/2
          );
        }

        resolve(this.canvas.toDataURL());
      };
    });
  }

  async updateWithNotification(count = 0) {
    const theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    const dataUrl = await this.drawWithBadge(theme, count);

    let link = document.querySelector('link[rel="icon"]');
    if (!link) {
      link = document.createElement('link');
      link.rel = 'icon';
      document.head.appendChild(link);
    }
    link.href = dataUrl;
  }
}

// Gebruik
const notificationFavicon = new NotificationFavicon();
notificationFavicon.updateWithNotification(3); // Toon badge met aantal 3

Samenvatting en volgende stappen

Adaptieve favicons zijn een kleine maar impactvolle manier om de gebruikerservaring te verbeteren. Ze tonen aandacht voor detail en respect voor gebruikersvoorkeuren, en dragen bij aan een meer gepolijste en professionele website.

Kies de juiste methode voor je project

Methode Beste voor Complexiteit Prestaties
HTML-only Statische sites, blogs, marketingpagina's Laag Uitstekend
JavaScript SPA's, aangepaste thema's, dynamische updates Gemiddeld Goed
Framework-integratie React/Vue/Nuxt-applicaties Gemiddeld Goed
Geavanceerde technieken Notificatiesystemen, realtime updates Hoog Variabel

Implementatiechecklist

Voordat je je adaptieve faviconsysteem deployt:

  • [ ] Maak zowel lichte als donkere faviconversies
  • [ ] Test in meerdere browsers (Chrome, Firefox, Safari, Edge)
  • [ ] Controleer of wisselen werkt bij systeemthemawijzigingen
  • [ ] Test op mobiele apparaten (iOS Safari, Android Chrome)
  • [ ] Optimaliseer bestandsgrootten (houd ICO-bestanden onder 1KB)
  • [ ] Voeg geschikte fallbacks toe voor oudere browsers
  • [ ] Valideer implementatie met tools zoals Favicon.im

Prestatie-impact

Bij correcte implementatie hebben adaptieve favicons minimale prestatie-impact:

  • HTML-only methode: Nul JavaScript-overhead
  • Bestandsgrootte-impact: ~2-4KB totaal (lichte + donkere versie)
  • Laadtijd: Verwaarloosbaar bij juiste caching

Verdere stappen

Overweeg deze geavanceerde optimalisaties:

  • Preload essentiële favicon-assets voor directe wisseling
  • Gebruik WebP-formaat voor moderne browsers (met PNG-fallbacks)
  • Implementeer dynamische favicon-badges voor notificaties
  • Voeg favicon-animaties toe voor speciale evenementen of statussen

Door adaptieve favicons doordacht te implementeren, creëer je een meer samenhangende en gebruiksvriendelijke webervaring die zich aanpast aan moderne gebruikersvoorkeuren.

Check Your Favicon

Use favicon.im to quickly check if your favicon is configured correctly. Our free tool ensures your website's favicon displays properly across all browsers and devices.

Free Public Service

Favicon.im is a completely free public service trusted by developers worldwide.

15M+
Monthly Favicon Requests
100%
Free Forever