Snippets and children

Svelte · Practical · 12 min

Snippets are how Svelte 5 does layout components, lists with custom rows and reusable template fragments.

A snippet is a reusable chunk of markup with parameters, declared with {#snippet name(params)}...{/snippet} and rendered with {@render name(args)}. Snippets can reference state in the scope where they are declared.

They replace Svelte 4 slots for passing content into components:

  • Content placed between a component's tags becomes an implicit `children` snippet prop. The child renders it with {@render children?.()} (the ?. handles the case where nothing was passed).
  • Snippets declared directly inside a component's tags become props with the snippet's name: write {#snippet header()}...{/snippet} inside <Table> and the table receives a header prop.
  • Snippets can take arguments, so a child can pass data back, like a list component that renders each row with the parent's snippet: {@render row(item)}.

Because snippets are ordinary values you can pass them explicitly (<List {row} />), check them ({#if footer}), and provide fallbacks with {:else} branches.

In TypeScript, type them with Snippet from svelte: row: Snippet<[Item]> (the type parameter is a tuple of arguments).

Snippets also help within one component: extract a repeated piece of markup into a top-level snippet instead of creating a tiny new component.

Example

<!-- List.svelte -->
<script>
  let { items, row, empty, children } = $props();
</script>
<section>
  {@render children?.()}
  {#each items as item (item.id)}
    {@render row(item)}
  {:else}
    {#if empty}{@render empty()}{:else}<p>No items</p>{/if}
  {/each}
</section>

<!-- App.svelte -->
<script>
  import List from './List.svelte';
  const users = [{ id: 1, name: 'Ada', admin: true }, { id: 2, name: 'Linus' }];
</script>

<List items={users}>
  <h2>Team</h2>                          <!-- becomes the children snippet -->
  {#snippet row(user)}
    <p>{user.name} {user.admin ? '(admin)' : ''}</p>
  {/snippet}
</List>

Remember

  • {#snippet name(args)} declares markup; {@render name(x)} renders it
  • Content between component tags is the children snippet prop
  • Snippets with parameters let children hand data back to the parent's markup

Watch out for

  • Forgetting ?.() when rendering an optional snippet, which throws when the parent passed nothing.

Check yourself

  1. Inside `<Card>...</Card>` the parent writes a paragraph. How does Card render it?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: svelte.dev/docs/svelte/snippet

Builds on

Unlocks

Nothing builds on this yet.