Svelte Slots
By Flavio Copes
Learn how Svelte 5 uses snippets and render tags to pass content into components, including default content and named snippets.
Svelte 5 uses snippets to pass content into a component.
The content between a component’s opening and closing tags becomes a snippet named children.
Here is a Button.svelte component:
<script>
let { children } = $props()
</script>
<button>
{@render children()}
</button>
You can pass the button text from the parent:
<script>
import Button from './Button.svelte'
</script>
<Button>Save</Button>
Default content
Check if the snippet exists when the content is optional:
<script>
let { children } = $props()
</script>
<button>
{#if children}
{@render children()}
{:else}
Save
{/if}
</button>
The component renders Save when the parent does not pass content.
Named snippets
Use named snippets when a component accepts content in several places.
Here is a Card.svelte component:
<script>
let { header, children, footer } = $props()
</script>
<article>
<header>{@render header()}</header>
<div>{@render children()}</div>
{#if footer}
<footer>{@render footer()}</footer>
{/if}
</article>
Pass the named snippets from the parent:
<Card>
{#snippet header()}
<h2>Account</h2>
{/snippet}
<p>Update your account details.</p>
{#snippet footer()}
<button>Save</button>
{/snippet}
</Card>
The paragraph becomes children. The two snippet blocks become the header and footer props.
The old slot syntax
Svelte 3 and 4 used the <slot> element:
<button><slot /></button>
This syntax still works in Svelte 5 legacy mode. Use snippets and {@render} in new components.