1 min de lecture

Où sont passées mes flèches ? Une histoire de sprites astro-icon

Chaque arrow-right du site a disparu silencieusement sur desktop alors que arrow-left s'affichait très bien. Le coupable : la déduplication de sprites SVG rencontrant les templates d'îlots Astro.

AstroTypeScript

Chaque pixelarticons:arrow-right de ce site a disparu du jour au lendemain — tandis que arrow-left continuait de s'afficher. Aucune erreur, aucune requête manquante. Juste des carrés vides.

Le mécanisme

astro-icon déduplique les icônes par page : le premier rendu d'un nom émet la définition <symbol>, tous les suivants n'émettent qu'un <use href="#..."> nu. C'est l'ordre du document qui décide qui est premier.

Sur ce site, le premier arrow-right se trouvait dans le menu latéral mobile — un îlot Astro qui livre le contenu de son slot dans un <template data-astro-template> inerte jusqu'à l'hydratation. Sur desktop, cet îlot ne s'hydrate jamais : le symbole n'entre donc jamais dans le DOM vivant, et les 28 références <use> ne résolvent plus rien.

<template data-astro-template="workPanel">
  <svg data-icon="pixelarticons:arrow-right">
    <symbol id="ai:pixelarticons:arrow-right">…</symbol>
    <use href="#ai:pixelarticons:arrow-right" />
  </svg>
</template>

<!-- partout ailleurs sur la page -->
<svg data-icon="pixelarticons:arrow-right">
  <use href="#ai:pixelarticons:arrow-right" /> <!-- ne pointe sur rien -->
</svg>

Le correctif

Un inlining partiel ne peut pas marcher — les rendus inline font eux aussi avancer le compteur par nom. La seule politique cohérente est un wrapper local Icon.astro qui force is:inline partout, échangeant quelques Ko de corps SVG répétés (et très compressibles) contre la correction.

Leçon : toute déduplication indexée sur l'ordre du document devient invalide dès qu'une partie de ce document est un template.