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.

AstroTypeScript

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.