# Snippets and {@render} — Svelte / SvelteKit

Source: https://www.skillbyai.com/en/svelte/c-snippets

> Reusable markup and the replacement for slots.

## Passing markup to components

A **snippet** is a named, reusable chunk of markup declared with `{#snippet name(params)}...{/snippet}` and rendered with `{@render name(args)}`. Content placed between a component's tags becomes the `children` snippet prop; snippets declared inside the component tags become props with the same name. Snippets are typed with `Snippet<[ParamTypes]>` from `svelte`. Optional snippets are rendered with `{@render footer?.()}` or guarded with `{#if}`. In Svelte 4 this was done with `<slot />`, named slots (`slot="header"`) and `let:` directives; slots still work in Svelte 5 for compatibility but snippets are the recommended approach.

## A generic table with row snippets

children and named snippet props.

```svelte
<!-- Table.svelte -->
<script lang="ts" generics="T">
  import type { Snippet } from 'svelte';

  let { rows, header, row, empty }: {
    rows: T[];
    header: Snippet;
    row: Snippet<[T]>;
    empty?: Snippet;
  } = $props();
</script>

<table>
  <thead><tr>{@render header()}</tr></thead>
  <tbody>
    {#each rows as item}
      <tr>{@render row(item)}</tr>
    {:else}
      {@render empty?.()}
    {/each}
  </tbody>
</table>

<!-- Usage -->
<Table rows={users}>
  {#snippet header()}<th>Name</th><th>Email</th>{/snippet}
  {#snippet row(u)}<td>{u.name}</td><td>{u.email}</td>{/snippet}
  {#snippet empty()}<tr><td colspan="2">No users</td></tr>{/snippet}
</Table>
```

## Snippets work locally too

Declare a snippet in the same component to avoid repeating a block of markup in several branches; it can read the surrounding state.

**Quiz:** Content placed between <Card> and </Card> is available to Card as...

- [ ] A string prop called content
- [ ] A $slots object
- [x] The children snippet prop, rendered with {@render children()}
- [ ] The default export of the component

*Answer:* The children snippet prop, rendered with {@render children()}. Snippets replace the default slot.
