Favicons : quand les petits pixels font les grands sites
Découvrez comment ajouter automatiquement des favicons aux liens externes et améliorer l'UX de votre site.
Publié le
Temps de lecture 1 min
J'aime soigner les petits détails qui rendent la lecture plus fluide et agréable. Récemment, je me suis attaqué à un micro-détail qui change tout : afficher automatiquement le favicon des sites externes devant chaque lien. L’idée ? Permettre aux lecteurs d’identifier visuellement la source d’un lien avant même de cliquer. C’est simple, élégant… et ça améliore vraiment l’expérience utilisateur.
Le défi initial
L’objectif était clair :
- Ajouter automatiquement un favicon devant chaque lien externe
- Garder un alignement parfait entre l’icône et le texte
- Souligner uniquement le texte (pas l’icône)
- Préserver les performances
- Et respecter les bonnes pratiques de sécurité ⠀ Autrement dit : pas de JS, pas de surcouche inutile — juste du HTML propre .
L’architecture technique
Traitement côté serveur
Tout se passe dans mon MarkdownProcessor, le service qui convertit le contenu Markdown en HTML. J’y ai ajouté une méthode dédiée : addFaviconsToExternalLinks().
private function addFaviconsToExternalLinks(string $html): string
{
$pattern = '/<a\s+href="(https?:\/\/([^\/\s"]+)[^"]*)"([^>]*)>([^<]*)<\/a>/i';
return preg_replace_callback($pattern, function (array $matches): string {
$fullUrl = $matches[1];
$domain = $matches[2];
$attributes = $matches[3];
$linkText = $matches[4];
*// Sécurisation automatique*
if (!str_contains($attributes, 'target=')) {
$attributes .= ' target="_blank"';
}
if (!str_contains($attributes, 'rel=')) {
$attributes .= ' rel="noreferrer nofollow"';
}
$attributes .= ' class="link"';
*// Génération du favicon via DuckDuckGo*
$faviconUrl = "https://icons.duckduckgo.com/ip3/{$domain}.ico";
$faviconImg = "<img src=\"{$faviconUrl}\" alt=\"\" class=\"favicon-img\" loading=\"lazy\">";
return "<a href=\"{$fullUrl}\"{$attributes}>{$faviconImg}<span class=\"link-text\">{$linkText}</span></a>";
}, $html) ?? $html;
}
Pourquoi cette approche ?
- Regex ciblée : le pattern capture uniquement les liens externes HTTP/HTTPS.
- Sécurité automatique : ajout des attributs
target="_blank"et rel="noreferrer nofollow". - HTML sémantique : séparation du texte dans un
<span>pour un contrôle CSS précis. - Service de favicon fiable : DuckDuckGo propose un endpoint public simple et rapide.
Le style CSS
L’enjeu côté front : aligner parfaitement l’icône et le texte, sans casser le flux du paragraphe. Voici le CSS final :
.content .favicon-img {
@apply inline-block w-4 h-4;
vertical-align: middle;
flex-shrink: 0;
margin-right: 0.125rem;
transform: translateY(-1px);
}
.content a.link {
text-decoration: none;
display: inline;
vertical-align: baseline;
}
.content a.link .link-text {
text-decoration: underline;
text-underline-offset: 2px;
text-decoration-thickness: 1.5px;
text-decoration-skip-ink: auto;
}
.content a.link:hover .link-text {
text-decoration-thickness: 2.5px;
}
Performance & sécurité
Lazy loading intégré
Chaque image est chargée avec :
<img src="..." loading="lazy" />
Les favicons ne se chargent que lorsqu’ils apparaissent à l’écran.
Cache naturel
DuckDuckGo renvoie les favicons avec un bon cache HTTP. Pas besoin de recharger les mêmes icônes à chaque page.
Sécurité renforcée
target="_blank"+rel="noreferrer nofollow": protection contre le tab nabbing.- Vérification stricte des URLs avant traitement.
alt="": accessibilité respectée pour les lecteurs d’écran.
Une todo pour améliorer
Il ne reste qu'à améliorer tout ça :
- Un système de cache pour réduire les requêtes externes
- Une icône générique si le favicon n'est pas disponible
Le mot de la fin
Ce genre de micro-fonctionnalité ne change pas le monde, mais il change la sensation du site. Un simple favicon peut rendre un lien plus lisible, plus crédible, plus agréable.
Et surtout, c’est l’exemple parfait d’un petit détail pensé avec soin — exactement le genre de choses que j’aime peaufiner : Symfony, High Performance PHP Framework for Web Development