Svelte Slots

By

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.

Tagged: Svelte · All topics
~~~

Related posts about svelte: