Foundation

Tags

A lowercase tag, like <div>, denotes a regular HTML element. A capitalised tag, such as <Widget> or <Namespace.Widget>, indicates a component.

<script>
	import Widget from './Widget.svelte';
</script>

<div>
	<Widget/>
</div>

Attributes and props

By default, attributes work exactly like their HTML counterparts.

<div class="foo">
	<button disabled>can't touch this</button>
</div>

As in HTML, values may be unquoted.

<input type=checkbox>

Attribute values can contain JavaScript expressions.

<a href="page/{p}">page {p}</a>

Or they can be JavaScript expressions.

<button disabled={!clickable}>...</button>

Boolean attributes are included on the element if their value is truthy and excluded if it's falsy.

All other attributes are included unless their value is nullish (null or undefined).

<input required="{false}" placeholder="This input field is not required" />
<div title="{null}">This div has no title attribute</div>

An expression might include characters that would cause syntax highlighting to fail in regular HTML, so quoting the value is permitted. The quotes do not affect how the value is parsed:

<button disabled="{number !== 42}">...</button>

When the attribute name and value match (name={name}), they can be replaced with {name}.

<!-- These are equivalent -->
<button disabled={disabled}>...</button>
<button {disabled}>...</button>

By convention, values passed to components are referred to as properties or props rather than attributes, which are a feature of the DOM.

As with elements, name={name} can be replaced with the {name} shorthand.

<Widget foo={bar} answer={42} text="hello"/>

Spread attributes allow many attributes or properties to be passed to an element or component at once.

An element or component can have multiple spread attributes, interspersed with regular ones.

<Widget {...things}/>

$$props references all props that are passed to a component, including ones that are not declared with export. It is not generally recommended, as it is difficult for Svelte to optimise. But it can be useful in rare cases – for example, when you don't know at compile time what props might be passed to a component.

<Widget {...$$props}/>

$$restProps contains only the props which are not declared with export. It can be used to pass down other unknown attributes to an element in a component. It shares the same optimisation problems as $$props, and is likewise not recommended.

<input {...$$restProps} />
DANGER

The value attribute of an input element or its children option elements must not be set with spread attributes when using bind:group or bind:checked. Svelte needs to be able to see the element's value directly in the markup in these cases so that it can link it to the bound variable.

Text expressions

{expression}

Text can also contain JavaScript expressions:

TIP

If you're using a regular expression (RegExp) literal notation, you'll need to wrap it in parentheses.

<h1>Hello {name}!</h1>
<p>{a} + {b} = {a + b}.</p>

<div>{(/^[A-Za-z ]+$/).test(value) ? x : y}</div>

Comments

You can use HTML comments inside components.

<!-- this is a comment! -->
<h1>Hello world</h1>

Comments beginning with svelte-ignore disable warnings for the next block of markup. Usually these are accessibility warnings; make sure that you're disabling them for a good reason.

<!-- svelte-ignore a11y-autofocus -->
<input bind:value={name} autofocus>

{#if ...}

{#if expression}...{/if}
{#if expression}...{:else if expression}...{/if}
{#if expression}...{:else}...{/if}

Content that is conditionally rendered can be wrapped in an if block.

{#if answer === 42}
	<p>what was the question?</p>
{/if}

Additional conditions can be added with {:else if expression}, optionally ending in an {:else} clause.

{#if porridge.temperature > 100}
	<p>too hot!</p>
{:else if 80 > porridge.temperature}
	<p>too cold!</p>
{:else}
	<p>just right!</p>
{/if}

{#each ...}

{#each expression as name}...{/each}
{#each expression as name, index}...{/each}
{#each expression as name (key)}...{/each}
{#each expression as name, index (key)}...{/each}
{#each expression as name}...{:else}...{/each}

Iterating over lists of values can be done with an each block.

<h1>Shopping list</h1>
<ul>
	{#each items as item}
		<li>{item.name} x {item.qty}</li>
	{/each}
</ul>

You can use each blocks to iterate over any array or array-like value — that is, any object with a length property.

An each block can also specify an index, equivalent to the second argument in an array.map(...) callback:

{#each items as item, i}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}

If a key expression is provided — which must uniquely identify each list item — Svelte will use it to diff the list when data changes, rather than adding or removing items at the end. The key can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.

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

<!-- or with additional index value -->
{#each items as item, i (item.id)}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}

You can freely use destructuring and rest patterns in each blocks.

{#each items as { id, name, qty }, i (id)}
	<li>{i + 1}: {name} x {qty}</li>
{/each}

{#each objects as { id, ...rest }}
	<li><span>{id}</span><MyComponent {...rest}/></li>
{/each}

{#each items as [id, ...rest]}
	<li><span>{id}</span><MyComponent values={rest}/></li>
{/each}

An each block can also have an {:else} clause, which is rendered if the list is empty.

{#each todos as todo}
	<p>{todo.text}</p>
{:else}
	<p>No tasks today!</p>
{/each}

{#await ...}

{#await expression}...{:then name}...{:catch name}...{/await}
{#await expression}...{:then name}...{/await}
{#await expression then name}...{/await}
{#await expression catch name}...{/await}

Await blocks allow you to branch on the three possible states of a Promise — pending, fulfilled or rejected. In SSR mode, only the pending state will be rendered on the server.

{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}

The catch block can be omitted if you don't need to render anything when the promise rejects (or no error is possible).

{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{/await}

If you don't care about the pending state, you can also omit the initial block.

{#await promise then value}
	<p>The value is {value}</p>
{/await}

Similarly, if you only want to show the error state, you can omit the then block.

{#await promise catch error}
	<p>The error is {error}</p>
{/await}

{#key ...}

{#key expression}...{/key}

Key blocks destroy and recreate their contents when the value of an expression changes.

This is useful if you want an element to play its transition whenever a value changes.

{#key value}
	<div transition:fade>{value}</div>
{/key}

When used around components, this will cause them to be reinstantiated and reinitialised.

{#key value}
	<Component />
{/key}

{@html ...}

{@html expression}

In a text expression, characters like < and > are escaped; however, with HTML expressions, they're not.

The expression should be valid standalone HTML — {@html "<div>"}content{@html "</div>"} will not work, because </div> is not valid HTML. It also will not compile Svelte code.

DANGER

Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.

<div class="blog-post">
	<h1>{post.title}</h1>
	{@html post.content}
</div>

{@debug ...}

{@debug}
{@debug var1, var2, ..., varN}

The {@debug ...} tag offers an alternative to console.log(...). It logs the values of specific variables whenever they change, and pauses code execution if you have devtools open.

<script>
	let user = {
		firstname: 'Ada',
		lastname: 'Lovelace'
	};
</script>

{@debug user}

<h1>Hello {user.firstname}!</h1>

{@debug ...} accepts a comma-separated list of variable names (not arbitrary expressions).

<!-- Compiles -->
{@debug user}
{@debug user1, user2, user3}

<!-- WON'T compile -->
{@debug user.firstname}
{@debug myArray[0]}
{@debug !isReady}
{@debug typeof user === 'object'}

The {@debug} tag without any arguments will insert a debugger statement that gets triggered when any state changes, as opposed to the specified variables.

{@const ...}

{@const assignment}

The {@const ...} tag defines a local constant.

<script>
  export let boxes;
</script>

{#each boxes as box}
  {@const area = box.width * box.height}
	{box.width} * {box.height} = {area}
{/each}

{@const} is only allowed as direct child of {#each}, {:then}, {:catch}, <Component /> or <svelte:fragment />.