sveltesveltekitsvelte-componentsvelte-5

How to Wrap Each Child with a Tag in Svelte 5?


In Svelte 5, how can I wrap each child with a tag like the example below?

{#if children}
  {#each children as child}
    <button
      onclick={() => {
        handleClick();
      }}
    >
      {@render child?.()}
    </button>
  {/each}
{/if}

Solution

  • You can't.

    Snippets are fragments made up of components, logic blocks and DOM that can contain absolutely anything, they are not iterable.

    You could pass a data array or multiple snippets, both of which could be iterated.

    Passing data example:

    <script>
        import List from './List.svelte';
    
        const items = [1, 2, 3];
    </script>
    
    <List {items}>
        {#snippet itemTemplate(item)}
            Item: {item}
        {/snippet}
    </List>
    
    <!-- List.svelte -->
    <script>
        const { items, itemTemplate } = $props();
    </script>
    
    <ul>
        {#each items as item}
            <li>{@render itemTemplate(item)}</li>
        {/each}
    </ul>
    

    Alternatively, wrap every child in a separate component along the lines of:

    <List>
      <ListItem>1</ListItem>
      <ListItem>2</ListItem>
      ...
    </List>
    

    Then this component can take of anything that needs to be added around the items. This is of course more verbose and the user needs to know that this should be added.