Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Bindings: bind

A binding connects the value of a form element with a variable in both directions: the user types — the variable changes, the code changes the variable — the field changes. It is shorter than writing a value attribute and an oninput handler by hand.

bind:value

<!-- src/routes/+page.svelte -->
<script>
  let text = $state('');
</script>
 
<input bind:value={text} placeholder="New task" />
<p>You are typing: {text}</p>
<button onclick={() => (text = '')}>Clear</button>

The paragraph repeats every typed letter, and the "Clear" button erases both the variable and the text in the field. Bind the value to a $state variable — otherwise the changes do not reach the rest of the markup.

Numbers

For type="number" and type="range" fields Svelte turns the string into a number itself:

<script>
  let priority = $state(1);
</script>
 
<input type="number" bind:value={priority} min="1" max="5" />
<p>Priority × 2 = {priority * 2}</p>

Type 3 — 6 appears below, not the string "33".

bind:checked

A checkbox is bound to a boolean:

<!-- src/routes/+page.svelte -->
<script>
  let todos = $state([
    { id: 1, text: 'Buy bread', done: false },
    { id: 2, text: 'Call Oleg', done: true }
  ]);
  let remaining = $derived(todos.filter((t) => !t.done).length);
</script>
 
{#each todos as todo (todo.id)}
  <label>
    <input type="checkbox" bind:checked={todo.done} />
    {todo.text}
  </label>
{/each}
 
<p>Left: {remaining}</p>

Clicking a checkbox changes todo.done in the array right away, and the "Left" counter is recalculated. No onchange handler is needed.

bind:this

bind:this puts the DOM element itself into a variable. You need it when you must work with the element directly — for example, to put the cursor into a field:

<script>
  let input;
 
  $effect(() => {
    input.focus();
  });
</script>
 
<input bind:this={input} placeholder="New task" />

When the page opens, the cursor is already in the field. The element appears in the variable only after the markup is rendered, so you use it in $effect or in handlers, not at the top of <script>.

Binding to a component prop

For a parent to write bind: on your component, the prop is marked with the $bindable rune:

<!-- src/lib/components/TodoInput.svelte -->
<script>
  let { value = $bindable('') } = $props();
</script>
 
<input bind:value placeholder="New task" />

Now in src/routes/+page.svelte you can write <TodoInput bind:value={text} />, and the parent's text variable changes as the user types. bind:value without braces is short for bind:value={value}.

Common mistake

Using value={text} instead of bind:value={text}. The field shows the initial value, but typing does not change the variable, and everything that depends on it stays the same. An attribute passes the value one way, bind: — both ways.

Thanks for reading!

Donate to the site — we work hard for you.