Svelte hat eine Reihe spezieller Tags mit Präfix <svelte:...>, die nicht in normales HTML passen, sondern mit dem Compiler oder Browser-Globals interagieren. Sie reichen vom Schreiben in den <head> der Seite über Window-Events bis zu Error Boundaries und rekursiven Komponenten. Dieser Artikel zeigt jeden Tag mit typischem Anwendungsfall und Code-Beispiel.

<svelte:head> – Inhalte in den HTML-<head>

Aus jeder Komponente lassen sich Inhalte direkt in den <head> der Seite schreiben — typisch für Title, Meta-Tags, Open-Graph oder Style-Imports:

svelte SeoMeta-Komponente
<script>
    let { title, description } = $props();
</script>

<svelte:head>
    <title>{title}</title>
    <meta name="description" content={description} />
    <meta property="og:title" content={title} />
</svelte:head>

Wenn mehrere Komponenten gleichzeitig in <head> schreiben, gewinnt die zuletzt gerenderte. In SvelteKit wird <svelte:head> korrekt sowohl beim SSR als auch bei Client-Navigation behandelt — Title und Meta-Tags sind immer aktuell.

<svelte:window> – Bindings und Events am Window

Direkter Zugriff auf Window-Properties und -Events ohne manuelles addEventListener:

svelte Resize-Listener
<script>
    let width = $state(0);
    let height = $state(0);
    let scrollY = $state(0);

    function handleKey(event) {
        if (event.key === 'Escape') console.log('ESC');
    }
</script>

<svelte:window
    bind:innerWidth={width}
    bind:innerHeight={height}
    bind:scrollY
    onkeydown={handleKey}
/>

<p>{width} × {height}, Scroll: {scrollY}</p>

Erlaubte Bindings: innerWidth, innerHeight, outerWidth, outerHeight, scrollX, scrollY, online, devicePixelRatio — alle reaktiv gehalten.

<svelte:document> und <svelte:body>

Analog zu Window, aber für document und <body>:

svelte Visibility-Tracking
<script>
    let visible = $state(true);

    function handleVisibility() {
        visible = !document.hidden;
    }
</script>

<svelte:document onvisibilitychange={handleVisibility} />

{#if !visible}<p>Tab im Hintergrund</p>{/if}
svelte Body-Listener
<svelte:body onclick={(e) => console.log('Body click:', e.target)} />

Praktisch für Listener, die garantiert auf Document- oder Body-Ebene laufen sollen.

<svelte:self> – rekursive Komponenten

Wenn eine Komponente sich selbst innerhalb des eigenen Markups verwenden soll, ist ein direkter Selbst-Import nicht möglich. Stattdessen <svelte:self>:

svelte TreeNode.svelte
<script>
    let { node } = $props();
</script>

<li>
    {node.label}
    {#if node.children?.length}
        <ul>
            {#each node.children as child (child.id)}
                <svelte:self node={child} />
            {/each}
        </ul>
    {/if}
</li>

Typisch für Trees, Verschachtelte Listen, Datei-Browser, Kommentar-Threads.

<svelte:options> – Compiler-Optionen pro Komponente

Mit <svelte:options> setzt man Compiler-Flags speziell für eine Komponente. Drei wichtige Anwendungsfälle:

Custom-Element

svelte Web-Component
<svelte:options customElement="my-counter" />

<script>
    let count = $state(0);
</script>

<button onclick={() => count++}>{count}</button>

Macht aus der Komponente ein Custom Element <my-counter>, nutzbar in jedem HTML-Kontext.

Immutable

svelte Immutable
<svelte:options immutable />

Hinweis an den Compiler, dass Props nicht tief mutiert werden — erlaubt Optimierungen beim Rendern.

Accessors

svelte Accessors
<svelte:options accessors />

Erzeugt Getter/Setter für alle Props auf der Komponenten-Instanz — relevant bei Custom-Elements, in Svelte-5-Reaktivität meist nicht mehr nötig.

<svelte:boundary> – Error Boundary (Svelte 5)

Eine der neuen Funktionen in Svelte 5: Fehler in einem Subtree abfangen und ein Fallback-Markup zeigen, statt die ganze App zu sprengen.

svelte Error Boundary
<svelte:boundary>
    <UnsicheresWidget />

    {#snippet failed(error, reset)}
        <div class="error">
            <p>Etwas ist schiefgelaufen: {error.message}</p>
            <button onclick={reset}>Erneut versuchen</button>
        </div>
    {/snippet}
</svelte:boundary>

failed ist ein Snippet mit zwei Argumenten: dem Fehler und einer Reset-Funktion, die den Boundary wieder normal rendern lässt.

Optional gibt es onerror={(error) => ...} für Logging und pending-Snippet für Suspense-ähnliches Loading-Verhalten.

<svelte:element> – dynamisches HTML-Element

Wenn der Tag-Name selbst eine Variable ist (z. B. h1 vs. h2 je nach Heading-Level), hilft <svelte:element>:

svelte Dynamic Heading
<script>
    let { level = 2, children } = $props();
    let tag = $derived(`h${level}`);
</script>

<svelte:element this={tag}>
    {@render children()}
</svelte:element>
svelte Verwendung
<Heading level={3}>Untertitel</Heading>

<svelte:element> akzeptiert die gleichen Attribute, Bindings und Events wie das normale Element.

Übersicht aller Special Elements

TagZweck
<svelte:head>Inhalte in den HTML-<head> schreiben
<svelte:window>Bindings und Events am window
<svelte:document>Bindings und Events am document
<svelte:body>Events am <body>
<svelte:self>Rekursive Verwendung der eigenen Komponente
<svelte:options>Compiler-Optionen pro Datei
<svelte:boundary>Error Boundary (Svelte 5)
<svelte:element>HTML-Element mit dynamischem Tag-Namen
<svelte:component>Dynamische Komponente (in Svelte 5 selten nötig)

Häufige Stolperfallen

<svelte:head> mehrfach gleichzeitig. Wenn zwei Komponenten gleichzeitig denselben Title schreiben, gewinnt die zuletzt gerenderte. In SvelteKit ist die übliche Konvention: <svelte:head> nur in Routen-Komponenten, nicht in Widgets.

<svelte:window> und <svelte:document> im SSR. Beide werden beim Server-Rendering einfach übersprungen, da kein window/document existiert. Innerhalb von $effect sind sie sicher.

<svelte:self> ohne Rekursions-Abbruch. Klassiker: Endlose Rekursion mit „Maximum call stack size exceeded”. Eine Abbruch-Bedingung ist Pflicht.

<svelte:boundary> als App-Wrapper. Eine Boundary auf App-Ebene fängt zwar alle Fehler ab, blockiert aber Hot-Reload-Diagnostik in Development. Lieber gezielt um spezifische, fehleranfällige Bereiche legen.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Components

Zur Übersicht