Skip to content

Passing UI & Children

When you put markup between a component’s tags, Svelte hands it to the component as a snippet prop named children. The component renders it with {@render children()}.

Card.svelte
<script>
let { children } = $props();
</script>
<div class="card">
{@render children()} <!-- whatever the parent nested goes here -->
</div>
<!-- Parent -->
<Card>
<h2>Title</h2>
<p>Any markup here becomes the card's children.</p>
</Card>

This is the Svelte 5 equivalent of React’s children (or the Svelte 4 default <slot>): a reusable wrapper component that doesn’t need to know what it wraps.

flowchart LR
  parent["<Card> ...markup... </Card>"] --> prop["child receives children snippet"]
  prop --> render["{@render children()}"]
  render --> out["markup rendered inside the card"]
Nested markup arrives as the children snippet

For components with several insertion points (a header, a body, a footer), pass named snippets as props. Define them in the parent with {#snippet name()} inside the component tags, and the child receives each as a prop.

Modal.svelte
<script>
let { header, children, footer } = $props();
</script>
<div class="modal">
<div class="modal-header">{@render header()}</div>
<div class="modal-body">{@render children()}</div>
<div class="modal-footer">{@render footer()}</div>
</div>
<Modal>
{#snippet header()}<h2>Confirm</h2>{/snippet}
<p>Are you sure?</p> <!-- default children -->
{#snippet footer()}<button>OK</button>{/snippet}
</Modal>

Because snippets take parameters, a component can pass data out to the markup the parent provides — the pattern React calls render props. The child invokes the snippet with a value; the parent’s snippet receives it:

List.svelte
<script>
let { items, row } = $props();
</script>
{#each items as item (item.id)}
{@render row(item)} <!-- pass each item back to the parent's snippet -->
{/each}
<List items={products}>
{#snippet row(product)}
<li>{product.name} — ${product.price}</li> <!-- parent decides the markup -->
{/snippet}
</List>

The child owns the iteration; the parent owns the per-item markup. This inversion — child provides data, parent provides presentation — is the render-prop pattern, expressed cleanly with snippets.

How does a component receive markup nested between its tags?
How do you provide multiple named insertion points to a component?
How does a Svelte component pass data out to parent-provided markup (render props)?