1 Min. Lesezeit
Wo sind meine Pfeile hin? Eine astro-icon-Sprite-Geschichte
Jedes arrow-right auf dieser Seite verschwand auf dem Desktop stillschweigend, während arrow-left einwandfrei rendert. Der Schuldige: SVG-Sprite-Deduplizierung trifft Astro-Island-Templates.
Jedes pixelarticons:arrow-right auf dieser Seite war eines Tages verschwunden — während arrow-left weiterhin sauber rendert. Keine Fehler, keine fehlenden Requests. Nur leere Quadrate.
Der Mechanismus
astro-icon dedupliziert Icons pro Seite: das erste Rendern eines Namens gibt die <symbol>-Definition aus, jedes weitere nur noch ein nacktes <use href="#...">. Die Dokumentreihenfolge entscheidet, wer zuerst kommt.
Auf dieser Seite lag das erste arrow-right im mobilen Seitenmenü — einer Astro-Insel, die ihren Slot-Inhalt bis zur Hydration in einem inerten <template data-astro-template> ausliefert. Auf dem Desktop hydriert diese Insel nie, das Symbol landet also nie im lebenden DOM, und alle 28 <use>-Referenzen lösen sich ins Nichts auf.
<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>
<!-- überall sonst auf der Seite -->
<svg data-icon="pixelarticons:arrow-right">
<use href="#ai:pixelarticons:arrow-right" /> <!-- zeigt auf nichts -->
</svg>
Die Lösung
Teilweises Inlining kann nicht funktionieren — auch Inline-Renderings erhöhen den Zähler pro Name. Die einzige konsistente Regel ist ein lokaler Icon.astro-Wrapper, der überall is:inline erzwingt und ein paar KB wiederholter (und gut komprimierbarer) SVG-Rümpfe gegen Korrektheit tauscht.
Lehre: Jede Deduplizierung, die auf der Dokumentreihenfolge beruht, ist in dem Moment unsicher, in dem ein Teil des Dokuments ein Template ist.