Snippets & @render
Snippets sind wiederverwendbare Markup-Bausteine — sie ersetzen die alten Slots und lassen sich sogar als Props übergeben.
Was ist ein Snippet?
Ein Snippet ist ein benanntes Stück Markup, das du an einer Stelle definierst
und an beliebig vielen Stellen mit {@render} einfügst — optional mit
Argumenten. Das spart Wiederholung innerhalb einer Komponente.
<script lang="ts">
let namen = ['Anna', 'Bob', 'Carla'];
</script>
<!-- Snippet definieren: wiederverwendbares Stück Markup mit Argument -->
{#snippet gruss(name)}
<li>Hallo, <strong>{name}</strong>!</li>
{/snippet}
<ul>
{#each namen as n}
{@render gruss(n)} <!-- Snippet aufrufen -->
{/each}
</ul>{#snippet name(arg)}…{/snippet} definiert, {@render name(arg)} rendert. Ein Snippet kann mehrere Argumente
nehmen — genau wie eine Funktion.
Die children-Prop: Ersatz für den Default-Slot
Der Inhalt, den eine Eltern-Komponente zwischen die Tags eines Kindes schreibt,
landet automatisch in einer speziellen Prop namens children. Du renderst sie mit {@render children()} — das ist der Nachfolger von <slot />.
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
children: Snippet; // der Inhalt zwischen den Tags
}
let { children }: Props = $props();
</script>
<div class="karte">
{@render children()}
</div><script lang="ts">
import Karte from './Karte.svelte';
</script>
<!-- Alles zwischen den Tags landet in der children-Prop -->
<Karte>
<h3>Titel</h3>
<p>Beliebiger Inhalt.</p>
</Karte>🛤️ Rails-Vergleich: yield, content_for & Partial-Blöcke
{@render children()} entspricht dem yield in einem
Rails-Layout. Benannte Snippet-Props funktionieren wie content_for, und ein
Snippet mit Argument ähnelt einem Partial, das mit render layout: … do |x| einen Block bekommt.
<%# yield entspricht der children-Prop %>
<%# app/views/layouts/application.html.erb %>
<div class="karte"><%= yield %></div>
<%# content_for / benannter Block ~ benannte Snippet-Prop %>
<% content_for :header do %>
<h1>Titel</h1>
<% end %>
<%# Partial mit Block ~ Snippet mit Argument %>
<%= render layout: "zeile" do |item| %>
<%= item.name %>
<% end %>Snippets als Props übergeben
Snippets sind Werte — du kannst sie also wie jede andere Prop an ein Kind reichen. So bestimmt die Eltern-Komponente, wie das Kind einzelne Teile rendert. Ein Snippet, das du direkt zwischen den Tags mit passendem Namen definierst, wird automatisch zur gleichnamigen Prop.
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
items: string[];
row: Snippet<[string]>; // Snippet mit einem string-Argument
}
let { items, row }: Props = $props();
</script>
<ul>
{#each items as item}
{@render row(item)}
{/each}
</ul><Liste items={namen}>
{#snippet row(name)}
<li class="fett">{name}</li>
{/snippet}
</Liste>
<!-- Ein Snippet, das direkt als Attribut übergeben ist, wird zur Prop 'row'. -->💡 Typisierung
Der Typ Snippet kommt aus svelte. Argumente gibst du als Tupel an: Snippet<[string]> ist ein Snippet mit einem string-Argument, Snippet ohne eckige Klammern nimmt keine Argumente.
Vergleich zu früheren Slots
Wenn du Svelte-4-Code kennst: Snippets ersetzen das komplette Slot-System. Ein Mapping macht die Umstellung leicht.
<!-- ❌ Svelte 4: slots -->
<slot /> <!-- Default-Inhalt -->
<slot name="header" /> <!-- benannter Slot -->
<slot item={x} /> <!-- Slot-Prop -->
<!-- ✅ Svelte 5: snippets -->
{@render children()} <!-- children-Prop -->
{@render header()} <!-- benannte Snippet-Prop -->
{@render item(x)} <!-- Snippet mit Argument -->Live: Liste mit lokalem Snippet
Snippets funktionieren komplett innerhalb einer Datei — deshalb können wir sie hier live
zeigen. Das Snippet zeile bekommt eine Aufgabe als Argument und wird pro
Listeneintrag gerendert:
- Props-Lektion lesen
- Snippets ausprobieren hoch
- Kaffee holen
Dasselbe Snippet zeile rendert jeden Eintrag — Markup einmal, Aufruf pro Zeile.
Zusammenfassung
💡 Das Wichtigste
{#snippet name(arg)}…{/snippet}definiert,{@render name(arg)}rendert.- Inhalt zwischen den Tags landet in der
children-Prop. - Snippets sind Werte und lassen sich als Props übergeben (Typ
Snippet<[…]>). - Snippets ersetzen die alten
<slot>-Mechanismen vollständig.
🎯 Probier es selbst
Ergänze die Demo um ein zweites Snippet badge(text), das ein kleines Label
rendert, und rufe es innerhalb von zeile für die Priorität auf. So siehst du,
dass Snippets sich gegenseitig aufrufen können.