iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

{#each}

{#each} iterates arrays. Always provide a key (the second argument to as) so Svelte can correctly identify items across reorders, inserts, deletes — otherwise inputs lose state on shuffle.

Keys, index, empty fallback, snippets

EXAMPLE
<script>
    let todos = $state([
        { id: 1, text: 'Learn Svelte', done: false },
        { id: 2, text: 'Ship MVP',     done: false },
        { id: 3, text: 'Sleep',          done: false },
    ]);

    function add() {
        todos.push({ id: Date.now(), text: 'New', done: false });
    }
    function remove(id) {
        todos = todos.filter(t => t.id !== id);
    }
</script>

<button onclick={add}>Add</button>
<button onclick={() => todos.reverse()}>Reverse</button>

<!-- 1) Iterate WITH A KEY (always) -->
<ul>
    {#each todos as t (t.id)}
        <li class:done={t.done}>
            <input type="checkbox" bind:checked={t.done}>
            <input bind:value={t.text}>
            <button onclick={() => remove(t.id)}>×</button>
        </li>
    {:else}
        <li class="empty">No todos yet.</li>
    {/each}
</ul>

<!-- 2) Index -->
<ol>
    {#each todos as t, i (t.id)}
        <li>#{i + 1}. {t.text}</li>
    {/each}
</ol>

<!-- 3) Destructure items -->
{#each users as { id, name, role } (id)}
    <li>{name} ({role})</li>
{/each}

<!-- 4) Iterate a Map / Set (Svelte 5 — both are reactive) -->
<script>
    let scores = $state(new Map([['Ada', 92], ['Bo', 78]]));
</script>

<ul>
    {#each scores as [name, score] (name)}
        <li>{name}: {score}</li>
    {/each}
</ul>

<!-- 5) Snippets — reusable markup blocks (Svelte 5) -->
{#snippet row(t)}
    <li class:done={t.done}>
        <input type="checkbox" bind:checked={t.done}>
        {t.text}
    </li>
{/snippet}

<ul>
    {#each todos as t (t.id)}
        {@render row(t)}
    {/each}
</ul>

Why it matters

Without a key, Svelte reuses DOM nodes positionally. Reordering re-uses the FIRST input’s state for the new first item — subtly wrong and a top source of “input shows the wrong value” bugs.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
{#each items as item (item.id)}
    <li>{item.name}</li>
{/each}
Try it Yourself »

Exercise

Iterate a list in markup.

{ items as item (item.id)}<li>{item.name}</li>{/each}

Test yourself

Q1. Iterate a list in markup with…
Q2. Provide a key with…
Q3. An empty list fallback uses…

Discussion

Loading…