Svelte
svelte/each-key
An each block whose items hold state (inputs, bindings, components, transitions) is keyed by a unique id, never by the index.
moderatestaticfe-svelte
Why
Without a key, Svelte updates an each block by position: when an item is removed or the list is sorted, the DOM nodes and component state of one row stay put and show the data of the next. Typed text, a checked box, an open panel or a running transition jumps to the wrong item. Using the index as the key has the same effect.
Fix
Add the item's unique id in parentheses after the as part: {#each todos as todo (todo.id)}. If the data has no id, create one when the item is created (crypto.randomUUID()). A list of plain text that never holds state may stay unkeyed.
Examples
<!-- bad -->
{#each todos as todo, i (i)}
<label><input type="checkbox" bind:checked={todo.done} /> {todo.title}</label>
{/each}
<!-- good -->
{#each todos as todo (todo.id)}
<label><input type="checkbox" bind:checked={todo.done} /> {todo.title}</label>
{/each}Sources
Facts
- Id
svelte/each-key- Severity
- moderate
- Check
- static checked in the source by
audit - Applies to
svelte- Only in projects with
sveltesveltekit- Taught by the skill
fe-svelteSvelte components- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain svelte/each-key