Template Syntax
Expressions
Section titled “Expressions”Any {expression} in markup embeds a JavaScript value. Because Svelte tracks reactivity through runes, when the expression depends on reactive state, the compiler updates that spot automatically.
<script> let user = $state({ name: 'Ada', points: 42 });</script>
<p>{user.name} has {user.points} points</p><p>{user.points > 40 ? 'VIP' : 'member'}</p> <!-- any JS expression --><img src={user.avatar} alt={user.name} /> <!-- in attributes too -->Logic blocks
Section titled “Logic blocks”Unlike JSX (which uses JavaScript && and .map()), Svelte has dedicated block syntax for control flow. It reads like HTML and the compiler optimizes it directly.
Conditionals — {#if}:
{#if loggedIn} <p>Welcome back</p>{:else if guest} <p>Browsing as guest</p>{:else} <button onclick={login}>Log in</button>{/if}Lists — {#each} (with a keyed identity via the (item.id) expression, so the compiler tracks items across reorders):
{#each todos as todo (todo.id)} <li>{todo.text}</li>{:else} <li>No todos yet</li> <!-- rendered when the list is empty -->{/each}Async — {#await} handles a promise’s pending, resolved, and rejected states inline:
{#await fetchUser()} <p>Loading…</p>{:then user} <p>Hello {user.name}</p>{:catch error} <p>Failed: {error.message}</p>{/await}flowchart TB
tmpl["Svelte markup"] --> ifb["{#if} conditional branches"]
tmpl --> each["{#each} lists (keyed by id)"]
tmpl --> awaitb["{#await} promise states"]
tmpl --> key["{#key} destroy and recreate on change"] The {#key expression} block destroys and recreates its contents whenever the expression changes — useful to force a re-mount (resetting state or replaying a transition).
Rendering raw HTML and snippets
Section titled “Rendering raw HTML and snippets”{@html string}injects a raw HTML string (bypassing escaping). Use it only for trusted/sanitized content — it’s an XSS vector otherwise.{@render snippet()}renders a snippet — Svelte 5’s reusable markup block that replaces the old<slot>mechanism. Snippets get a full lesson later; for now, know that{@render …}is how snippet content lands in the markup.
{@html sanitizedMarkdown}
{#snippet greeting(name)} <p>Hello {name}</p>{/snippet}{@render greeting('world')}