Snippets sind Svelte 5s Antwort auf Slots — und in fast jeder Hinsicht mächtiger. Sie sind benannt, können Argumente entgegennehmen, sind als TypeScript-Type abbildbar, lassen sich aus dem <script module>-Bereich exportieren und werden ganz normal als Props weitergereicht. Dieser Artikel zeigt die Syntax ({#snippet} und {@render}), den impliziten children-Prop, named Snippets, Snippets mit Parametern und die Migration aus Svelte 4.

Was ist ein Snippet?

Ein Snippet ist ein wiederverwendbares Stück Markup, das mit {#snippet name()} ... {/snippet} definiert und mit {@render name()} an einer beliebigen Stelle gerendert wird.

svelte Snippet definieren und rendern
<script>
    let users = [{ name: 'Anna' }, { name: 'Bernd' }];
</script>

{#snippet userBadge(user)}
    <span class="badge">{user.name}</span>
{/snippet}

{#each users as user}
    {@render userBadge(user)}
{/each}

<style>
    .badge {
        padding: 4px 8px;
        border-radius: 999px;
        background: #eef;
    }
</style>

Snippets sind lokal sichtbar im umschließenden Scope — sie können sich selbst, einander und Variablen aus dem Scope referenzieren.

Implizite children-Prop

Inhalte zwischen den Tags einer Komponente werden automatisch zur Snippet-Prop children:

svelte Card.svelte
<script>
    let { children } = $props();
</script>

<article class="card">
    {@render children()}
</article>
svelte Verwendung
<Card>
    <h2>Profil</h2>
    <p>Anna, 30 Jahre</p>
</Card>

Der Inhalt zwischen <Card> und </Card> landet in children und wird per {@render children()} ausgegeben.

Named Snippets als Props

Mehrere Inhaltsbereiche werden über benannte Snippets gelöst:

svelte Article.svelte
<script>
    let { header, footer, children } = $props();
</script>

<article>
    {#if header}
        <header>{@render header()}</header>
    {/if}

    <div class="body">
        {@render children()}
    </div>

    {#if footer}
        <footer>{@render footer()}</footer>
    {/if}
</article>
svelte Verwendung mit Snippet-Props
<Article>
    {#snippet header()}
        <h1>Titel</h1>
    {/snippet}

    <p>Hauptinhalt — landet automatisch in children.</p>

    {#snippet footer()}
        <small>Autor: Anna</small>
    {/snippet}
</Article>

Der Eltern-Komponent definiert die Snippets innerhalb der Komponenten-Tags — sie werden vom Compiler an die entsprechenden Props gebunden.

Snippets mit Argumenten

Anders als Slots können Snippets Parameter annehmen — perfekt für Listen, Tabellen oder generische Render-Patterns:

svelte List.svelte
<script>
    let { items, item } = $props();
</script>

<ul>
    {#each items as element, index}
        <li>
            {@render item(element, index)}
        </li>
    {/each}
</ul>
svelte Verwendung mit Argument-Snippet
<List items={users}>
    {#snippet item(user, index)}
        <strong>#{index + 1}</strong>
        {user.name}
    {/snippet}
</List>

Das ersetzt das Svelte-4-Konstrukt <slot {user} /> und <List let:user>{user.name}</List> mit einer expliziteren Funktions-artigen Schreibweise.

TypeScript-Typen für Snippets

Snippet aus dem svelte-Modul:

svelte Snippet ohne Argument
<script lang="ts">
    import type { Snippet } from 'svelte';

    type Props = {
        children: Snippet;
        header?: Snippet;
    };

    let { children, header }: Props = $props();
</script>
svelte Snippet mit typisierten Argumenten
<script lang="ts">
    import type { Snippet } from 'svelte';

    type Item = { id: string; name: string };

    type Props = {
        items: Item[];
        item: Snippet<[Item, number]>;
    };

    let { items, item }: Props = $props();
</script>

Snippet<[Type1, Type2, ...]> definiert eine Tupel der Argumente, die das Snippet beim Aufruf erwartet.

Snippets exportieren

Aus <script module> lassen sich Snippets auch als Modul-Export anbieten — sehr praktisch für UI-Bibliotheken:

svelte icons.svelte
<script module>
    export { iconHome, iconUser };
</script>

{#snippet iconHome()}
    <svg viewBox="0 0 24 24" width="24" height="24">
        <path d="M3 12L12 3l9 9..." />
    </svg>
{/snippet}

{#snippet iconUser()}
    <svg viewBox="0 0 24 24" width="24" height="24">
        <circle cx="12" cy="8" r="4" />
    </svg>
{/snippet}
svelte Verwendung
<script>
    import { iconHome, iconUser } from '$lib/icons.svelte';
</script>

{@render iconHome()}
{@render iconUser()}

Das ist gleichzeitig eine simple, performante Alternative zu Icon-Komponenten-Libraries.

Snippets als normale Werte

Snippets sind in Svelte 5 first-class — sie lassen sich in Variablen speichern und an mehrere Stellen weitergeben:

svelte Snippet wiederverwenden
<script>
    let { variant } = $props();
</script>

{#snippet primary()}<span class="primary">!</span>{/snippet}
{#snippet danger()}<span class="danger">!</span>{/snippet}

{@render (variant === 'danger' ? danger : primary)()}

Einsatz typischerweise in Render-Logik, die abhängig vom State unterschiedliche Snippets verwendet.

Migration aus Svelte 4

Svelte 4Svelte 5
<slot />{@render children()} mit let { children } = $props();
<slot name="header" />{@render header()} mit named Snippet-Prop
<slot {value} /> + let:valueSnippet mit Argument
<svelte:fragment slot="x">{#snippet x()}...{/snippet}
$$slots.header{#if header}...{/if} (Snippet-Prop existiert oder nicht)

Häufige Stolperfallen

Snippet-Aufruf vergessen. {children} allein rendert das Snippet nicht — es muss {@render children()} heißen.

Optional-Chaining beim Aufruf. Bei optionalen Snippet-Props prüfen oder Optional-Chaining nutzen: {@render header?.()} oder {#if header}{@render header()}{/if}.

Snippet außerhalb seines Scopes verwenden. Snippets sind lexikalisch — sie sehen den umschließenden Scope. Ein Snippet aus Komponente A lässt sich nicht in Komponente B verwenden, ohne als Prop weiterzureichen.

Reservierte Argument-Namen. Snippet-Parameter funktionieren wie normale Funktionsparameter. Destrukturierung und Defaults sind erlaubt, Rest-Parameter dagegen nicht.

Slot/Snippet-Mix in Bestandscode. Im Legacy-Modus laufen Slots weiter. In einer Runes-Komponente mischst du sie nicht — entweder ganz auf Snippets umstellen oder Komponente vorerst im Legacy-Modus belassen.

Weiterführende Ressourcen

Externe Quellen

Verwandte Artikel

/ Weiter

Zurück zu Components

Zur Übersicht