new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Svelte · Language · all subjects

core/template-syntax

188 notes in this subject, read out of this brain and free to use. This is page 1 of 4.

Keyed each blocks syntax with key expression

A keyed each block uses syntax {#each expression as name (key)}...{/each} or with index {#each expression as name, index (key)}...{/each}. The key expression must uniquely identify each list item and allows Svelte to intelligently update the list by inserting, moving, and deleting items rather than updating in place.

Each block accepts arrays, array-like objects, and iterables

Each blocks iterate over arrays, array-like objects (anything with a length property), or iterables like Map and Set. Internally, they are converted to arrays with Array.from(). If the value is null or undefined, it is treated as an empty array.

Else block in each statement

An each block can have an {#each expression as name}...{:else}...{/each} clause. The else block is rendered if the list is empty.

Key expression recommendations in each blocks

The key in a keyed each block can be any object, but strings and numbers are recommended since they allow identity to persist when the objects themselves change.

Each block basic syntax with expression and name

The basic each block syntax is {#each expression as name}...{/each}. This iterates over the values in the expression and binds each value to the name variable.

Each block with index parameter

An each block can optionally specify an index as a second parameter: {#each expression as name, index}...{/each}. The index is equivalent to the second argument in an array.map() callback.

Destructuring and rest patterns in each blocks

Each blocks support destructuring and rest patterns for the item variable. Examples include {#each items as { id, name, qty }, i (id)} for object destructuring and {#each items as [id, ...rest]} for array destructuring.

Each block without item variable

An each block can omit the 'as' part to render something n times: {#each expression}...{/each} or with index {#each expression, index}...{/each}. This is useful for rendering a fixed number of iterations, such as {#each { length: 8 }} to render 8 times.

{#key} with transitions

The {#key} block is useful for playing a transition whenever a value changes, as it destroys and recreates the containing elements.

{#key} block syntax

The {#key expression}...{/key} block destroys and recreates its contents when the value of the expression changes.

{:catch} branch in {#await} handles rejection

The {:catch name} branch renders when the promise is rejected, with the error object bound to the specified name variable. This branch can be omitted if rejection handling is not needed.

{#await} server-side rendering behavior

During server-side rendering, only the pending branch of an {#await} block will be rendered. If the expression is not a Promise, the then branch will be rendered during server-side rendering.

{#await} with dynamic import for lazy component loading

You can use {#await} with dynamic import() to render components lazily. The syntax is {#await import('./Component.svelte') then { default: Component }} where Component is destructured from the import and then rendered in the template.

{#await} omitting pending state syntax

To skip the pending state and only render content when the promise resolves, use the shorthand syntax {#await expression then value} without an initial pending block.

{#await} pending branch renders when promise is pending

The first block of an {#await} statement renders while the promise is in a pending state, before it resolves or rejects.

{#await} omitting fulfilled state syntax

To only render the error state and skip the fulfilled state, use {#await expression catch error} with no {:then} block.

{#await} block syntax and structure

The {#await} block allows branching on the three states of a Promise: pending, fulfilled, or rejected. The full syntax is {#await expression}...{:then name}...{:catch name}...{/await}. The then and catch blocks can be omitted individually if not needed. You can write {#await expression}...{:then name}...{/await} to omit the catch block, {#await expression then name}...{/await} to omit the pending block, or {#await expression catch error}...{/await} to omit the then block.

{:then} branch in {#await} receives fulfilled value

The {:then name} branch renders when the promise is fulfilled or resolves, with the resolved value bound to the specified name variable. If the expression is not a Promise, only the then branch will be rendered.

@render fallback content with if-else

Alternatively to optional chaining, use an {#if ...} block with an {:else} clause to render fallback content when a snippet is not defined. The {#if children} block checks if the snippet exists, and {:else} provides fallback content.

snippet tag definition and @render usage example

Snippets are defined using the {#snippet name(params)} block syntax. Multiple {@render name(args)} tags can then invoke the same snippet with different arguments, for example {#snippet sum(a, b)} defines a snippet that can be rendered multiple times with {@render sum(1, 2)}, {@render sum(3, 4)}, etc.

@render tag basic syntax

The {@render ...} tag is used to render a snippet. The syntax is {@render snippetName(args)} where snippetName is an identifier and args are arguments passed to the snippet.

@render optional snippets with optional chaining

When a snippet might be undefined, use optional chaining syntax {@render children?.()} to only render the snippet when it is defined. If it is undefined, nothing renders.

@render with arbitrary JavaScript expressions

The {@render} tag can accept arbitrary JavaScript expressions, not just identifiers. For example, {@render (cool ? coolSnippet : lameSnippet)()} renders a different snippet based on a condition.

Render tag syntax {@render}

Snippets are rendered using the {@render snippet()} tag syntax. The render tag invokes a snippet and optionally passes arguments to it.

Snippet scope and visibility

Snippets can be declared anywhere inside a component and are visible to their siblings and children in the same lexical scope. Snippets can reference values declared outside themselves, such as values from the <script> tag or {#each} blocks. Nested snippets are only accessible within their parent scope.

Exported snippets require Svelte 5.5.0 or newer

The ability to export snippets from a <script module> block requires Svelte version 5.5.0 or newer.

Snippets replace slots in Svelte 5

Snippets are more powerful and flexible than Svelte 4 slots and have replaced them. Slots have been deprecated in Svelte 5 in favor of snippets.

Self-referencing and mutually recursive snippets

Snippets can reference themselves and each other, enabling recursion and mutual recursion patterns within a component.

Snippet declaration syntax

Snippets are declared with the {#snippet name()}...{/snippet} block syntax. They can have zero or more parameters: {#snippet name(param1, param2, paramN)}...{/snippet}. Like function declarations, snippets can have arbitrary parameters with default values and parameter destructuring. Snippets cannot use rest parameters.

Programmatic snippet creation with createRawSnippet

Snippets can be created programmatically using the createRawSnippet API, which is intended for advanced use cases.

Passing snippets as explicit props

Snippets are values just like any other and can be passed to components as explicit props using the {prop} syntax. The receiving component receives them via $props() and renders them with {@render}.

Implicit snippet props

Snippets declared directly inside a component implicitly become props on that component. This provides a convenient authoring pattern where child snippets are automatically available to the component without explicit prop passing.

Generic snippet typing with TypeScript

Snippets can use generic types in TypeScript. Define a generic component with generics="T" and type snippets relative to that generic, such as row: Snippet<[T]> to ensure the row snippet receives the same type as the data array.

Snippet type interface from svelte

Snippets implement the Snippet<T> interface imported from 'svelte'. The type parameter is a tuple of the snippet's parameter types. For example, Snippet<[any]> is a snippet with one parameter of type any, and Snippet with no type argument is a snippet with no parameters.

Exporting snippets from module context

Snippets declared at the top level of a .svelte file can be exported from a <script module> block for use in other components, provided they do not reference any declarations from non-module <script> blocks, either directly or indirectly through other snippets.

Implicit children snippet

Any content inside component tags that is not a snippet declaration implicitly becomes part of a special 'children' snippet prop. The component can access this via let { children } = $props() and render it with {@render children()}.

children prop name conflict restriction

You cannot have a prop called 'children' if you also have content inside the component tags, because any non-snippet content becomes the implicit children snippet. Avoid naming props 'children' for this reason.

TypeScript snippet typing example

To type snippets in TypeScript, import Snippet from 'svelte' and define an interface with snippet props. Example: interface Props { data: any[]; children: Snippet; row: Snippet<[any]>; }. The type argument is a tuple of parameter types.

Optional snippet props rendering

Snippet props can be optional. To render an optional snippet, use either optional chaining {@render snippet?.()} to render nothing if undefined, or use an {#if} block to render fallback content.

{@html} requires valid standalone HTML

The expression passed to {@html} must be valid standalone HTML. Splitting HTML across multiple {@html} tags will not work, for example {@html '<div>'}content{@html '</div>'} is invalid because neither '<div>' nor '</div>' is valid standalone HTML. {@html} also will not compile Svelte code.

{@html} security consideration: XSS attacks

The string passed to {@html} must either be escaped or only populated with values under your control to prevent XSS attacks. Never render unsanitized content.

{@html} tag syntax and usage

The {@html ...} tag injects raw HTML into a component. The syntax is {@html content} where content is an expression that evaluates to an HTML string.

{@const} tag defines local constants

The {@const} tag defines a local constant within a template block. Example: {#each boxes as box} {@const area = box.width * box.height} {box.width} * {box.height} = {area} {/each}

{@const} is legacy syntax, use {const x = $derived(y)} instead

The {@const x = y} tag is legacy syntax. The modern replacement is the {const x = $derived(y)} declaration tag syntax.

{@const} placement rules: immediate child of blocks only

{@const} is only allowed as an immediate child of a block such as {#if ...}, {#each ...}, {#snippet ...} and so on, or a <Component /> or a <svelte:boundary>.

@attach directive basic syntax and purpose

The {@attach ...} directive runs functions as effects when an element is mounted to the DOM or when state read inside the function updates. An element can have any number of attachments. Attachments are available in Svelte 5.29 and newer.

Attachment function signature and return value

An attachment function receives the element as its parameter. It can optionally return a cleanup function that is called before the attachment re-runs or after the element is removed from the DOM.

fromAction converter function

Use fromAction from 'svelte/attachments' to convert actions to attachments. This allows using actions from libraries with components or other contexts that require attachments.

Attachment TypeScript type

The Attachment type is exported from 'svelte/attachments'. It represents a function that receives an element and optionally returns a cleanup function.

Attachment factories pattern

A function can return an attachment. This allows creating reusable attachment factories. When the factory function takes parameters (like content), the attachment re-runs whenever those parameters change or whenever state is read inside the attachment function.

createAttachmentKey function

Use createAttachmentKey from 'svelte/attachments' to programmatically add attachments to an object that will be spread onto a component or element.

Attachments on components create Symbol-keyed props

When {@attach ...} is used on a component, it creates a prop whose key is a Symbol. If the component spreads props onto an element, the element will receive those attachments. This enables creating wrapper components that augment elements.

Inline attachments with nested effects

Attachments can be created inline directly in the template. An attachment can contain a nested $effect. The outer effect (the attachment itself) runs once when the element mounts if it doesn't read reactive state. Inner effects run whenever their dependencies change.

Conditional attachments with falsy values

Falsy values like false or undefined are treated as no attachment, enabling conditional usage. Example: {@attach enabled && myAttachment}.

Attachment reactivity and re-run behavior

Attachments are fully reactive: {@attach foo(bar)} will re-run whenever foo changes, bar changes, or any state read inside foo changes. To avoid expensive setup work re-running, pass the data inside a function and read it in a child effect within the attachment.

@debug accepts comma-separated variable names

The {@debug} tag accepts a comma-separated list of variable names. Multiple variables can be monitored in a single tag: {@debug user1, user2, user3}

@debug does not accept arbitrary expressions

The {@debug} tag only accepts variable names, not arbitrary expressions. Constructs like {@debug user.firstname}, {@debug myArray[0]}, {@debug !isReady}, and {@debug typeof user === 'object'} will not compile.

@debug without arguments triggers on any state change

When {@debug} is used without any arguments, it inserts a debugger statement that is triggered whenever any state changes, not just specific variables.

@debug tag purpose and behavior

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

Declaration tags with const and let

Declaration tags define local variables inside markup using either const or let syntax. They are written as {const variableName = value} or {let variableName = value} and are available since Svelte 5.56.

Give your agent this brain