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 3 of 4.

Multiple style: directives on single element

Multiple style: directives can be applied to a single element. For example: style:color style:width="12rem" style:background-color={darkMode ? 'black' : 'white'} sets three styles on the same element.

style: directive with |important modifier

The |important modifier can be used with style: directives to mark a style as important. For example, style:color|important="red" sets color to red with !important priority.

style: directive with CSS custom properties

CSS custom properties (CSS variables) can be set using style: directives. For example, style:--columns={columns} sets the --columns custom property to the value of the columns variable.

class attribute accepts objects since Svelte 5.16

Since Svelte 5.16, the class attribute can accept an object value. Truthy keys in the object are added as classes. The object is converted to a string using clsx. For example: <div class={{ cool, lame: !cool }}> results in class="cool" if cool is truthy, or class="lame" otherwise.

class: directive vs class attribute

Prior to Svelte 5.16, the class: directive was the most convenient way to set classes conditionally. As of Svelte 5.16, the class attribute with objects and arrays is more powerful and composable. class: directive should be avoided in favor of the class attribute unless using an older version of Svelte.

class: directive conditional class binding

The class: directive can be used to conditionally add classes to elements. Syntax: class:classname={condition}. When the classname matches the variable name, shorthand syntax is available: class:classname.

ClassValue type for type-safe class attributes

Since Svelte 5.19, Svelte exposes the ClassValue type which represents the type of value that the class attribute on elements accept. Import it from 'svelte/elements' and use it for type-safe class names in component props.

class attribute arrays and objects can be nested and flattened

Arrays can contain nested arrays and objects, and clsx will flatten them. This is useful for combining local classes with props passed to components.

class attribute accepts arrays since Svelte 5.16

Since Svelte 5.16, the class attribute can accept an array value. Truthy values in the array are combined into the class string. The array is converted to a string using clsx. For example: <div class={[faded && 'saturate-0 opacity-50', large && 'scale-200']}> results in class="saturate-0 opacity-50 scale-200" if both faded and large are truthy.

Falsy values in class attribute stringified as strings

For historical reasons, falsy values like false and NaN are stringified as strings (class="false"), though class={undefined} or null cause the attribute to be omitted altogether. In a future version of Svelte, all falsy values will cause class to be omitted.

class attribute with primitive values

Primitive values are treated like any other attribute and can be set on the class attribute using standard JavaScript expressions. For example: <div class={large ? 'large' : 'small'}>.</div>

Sequential $derived with await shows await_waterfall warning

When writing sequential $derived expressions with await, like let a = $derived(await one(x)); followed by let b = $derived(await two(y));, b will not be created until a has resolved. While they will update independently once created, Svelte will issue an await_waterfall runtime warning for this pattern.

Synchronized updates with await expressions

When an await expression depends on a particular piece of state, changes to that state will not be reflected in the UI until the asynchronous work has completed, so that the UI is not left in an inconsistent state. This ensures the UI remains consistent during async operations.

Enable experimental async with svelte.config.js

To use await expressions, add the experimental.async option to svelte.config.js under compilerOptions: export default { compilerOptions: { experimental: { async: true } } };

await expressions available in Svelte 5.36+

As of Svelte 5.36, the await keyword can be used inside components in three places: at the top level of the component's <script>, inside $derived(...) declarations, and inside markup. This feature is experimental and requires opting in with the experimental.async option in svelte.config.js. The experimental flag will be removed in Svelte 6.

Loading states with svelte:boundary and pending snippet

To render placeholder UI during async operations, wrap content in a <svelte:boundary> with a pending snippet. The pending snippet is shown when the boundary is first created, but not for subsequent updates, which are globally coordinated.

$effect.pending() detects subsequent async work

After a boundary's contents have resolved for the first time and replaced the pending snippet, $effect.pending() can be used to detect subsequent async work. This is useful for displaying a 'validating input' spinner next to form fields.

settled() promise resolves after async updates complete

The settled() function from 'svelte' returns a promise that resolves when the current update is complete. This ensures any updates affected by state changes have been applied before continuing execution.

Error handling with await expressions

Errors in await expressions will bubble to the nearest error boundary (svelte:boundary).

Server-side rendering with async render() API

Svelte supports asynchronous server-side rendering with the render(...) API from 'svelte/server'. To use it, await the return value: const { head, body } = await render(App);. If using SvelteKit, this is handled automatically.

Parallel execution of independent await expressions

When multiple independent await expressions appear in markup, Svelte will run them in parallel. For example, {await one(x)} and {await two(y)} will execute concurrently even though they appear sequentially in the template.

SSR pending snippet behavior with await render()

During SSR, if a <svelte:boundary> with a pending snippet is encountered, that pending snippet will be rendered while the rest is ignored. All await expressions outside boundaries with pending snippets will resolve and render their contents before await render(...) returns.

fork() API for preloading async operations

The fork(...) API, added in Svelte 5.42, enables running await expressions that are expected to happen in the near future. It is mainly intended for frameworks like SvelteKit to implement preloading. fork() returns a Fork object with commit() and discard() methods to apply or cancel the forked updates.

fork() example for menu preloading

Example: Use fork() on onfocusin/onpointerenter to preload async work. Call pending.commit() on onclick to apply the forked changes, or pending.discard() on onfocusout/onpointerleave to cancel them. If fork was never created (pending is null), a fallback action occurs.

Experimental async feature subject to breaking changes

As an experimental feature, the details of how await is handled and related APIs like $effect.pending() are subject to breaking changes outside of a semver major release, though breaking changes are intended to be minimal.

Block effects run before $effect.pre with experimental.async

When experimental.async is true, block effects like {#if ...} and {#each ...} now run before $effect.pre or beforeUpdate in the same component. In very rare situations, this could update a block that should no longer exist if you update state inside an effect, which should be avoided.

Overlapping updates with await expressions

Updates can overlap with await expressions—a fast update will be reflected in the UI while an earlier slow update is still ongoing.

Use keyed each blocks for better performance

Prefer to use keyed each blocks — this improves performance by allowing Svelte to surgically insert or remove items rather than updating the DOM belonging to existing items. The key must uniquely identify the object. Do not use the index as a key.

Replace use:action with {@attach}

Use {@attach ...} instead of use:action.

Replace <slot> with {#snippet} and {@render}

Use {#snippet ...} and {@render ...} instead of <slot>, $$slots and <svelte:fragment>.

Snippets for reusable markup chunks

Snippets are a way to define reusable chunks of markup that can be instantiated with the {@render ...} tag, or passed to components as props. They must be declared within the template. Snippets declared at the top level of a component (not inside elements or blocks) can be referenced inside <script>. A snippet that doesn't reference component state is also available in a <script module>, in which case it can be exported for use by other components.

Avoid destructuring in each blocks when mutating items

Avoid destructuring if you need to mutate the item (with something like bind:value={item.count}, for example).

bind:devicePixelContentBoxSize requires higher browser version

The bind:devicePixelContentBoxSize directive requires Firefox 93 or later. It is not supported in Chrome/Edge or Safari.

inert attribute on outroing elements in Svelte 4

The inert attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction.

Default slot bindings isolation in Svelte 4

Default slot bindings are no longer exposed to named slots and vice versa. Variables bound with let: in the default slot are not available in named slots.

Transitions local by default in Svelte 4

Transitions are now local by default, meaning they will not play if within a nested control flow block (each/if/await/key) when a block above it (not the direct parent) is created/destroyed. Add the |global modifier to make transitions play when any control flow block above is created/destroyed.

Whitespace at start and end of tags is removed

In Svelte 5, whitespace at the beginning and end of a tag is removed completely. Reintroduce space by moving it outside the tag or including it as an expression: {' '}

Bindings now react to form reset events

In Svelte 5, bindings take into account the reset event of forms, preventing values from getting out of sync with the DOM.

bind:files accepts only null, undefined, or FileList

In Svelte 5, bind:files is a two-way binding and can only be set to null, undefined, or a FileList object.

contenteditable binding prevents reactive content updates

If a contenteditable node has a binding and reactive content inside it (e.g., <div contenteditable bind:textContent>count is {count}</div>), the reactive value will not update because the binding takes full control.

@const destructuring assignments are no longer allowed

In Svelte 5, assignments to destructured parts of a @const declaration are not allowed. This was previously an oversight.

HTML structure is stricter in Svelte 5

Svelte 5 enforces strict HTML structure and will throw a compiler error for invalid structures that the browser would auto-repair. For example, <tr> must be inside <tbody>.

null and undefined render as empty string

In Svelte 5, null and undefined are rendered as empty strings instead of the string 'null' or 'undefined'. This aligns with most other frameworks.

Whitespace handling exceptions for pre tags

Whitespace inside <pre> tags is preserved as an exception to the general whitespace trimming rules in Svelte 5.

Whitespace between nodes is collapsed to one space

In Svelte 5, whitespace handling is simplified. Whitespace between nodes is collapsed to a single space, which differs from HTML where <p>foo<span> - bar</span></p> renders 'foo - bar' but Svelte renders 'foo- bar'.

each_key_duplicate error: keyed each block has duplicate keys

A keyed each block cannot have duplicate key values at different indexes. Each key must be unique across all items in the block.

Compile warning: attribute_illegal_colon

The attribute_illegal_colon warning is triggered when an attribute contains a colon character. Colons in attributes create ambiguity with Svelte directives and should be avoided.

Compile warning: block_empty

The block_empty warning is triggered when an empty block is detected in the template.

Compile warning: element_invalid_self_closing_tag

The element_invalid_self_closing_tag warning is triggered when a self-closing tag syntax is used on non-void HTML elements (e.g., `<div />`). HTML does not support self-closing tags for non-void elements, and browsers will parse them unexpectedly. Use an explicit closing tag instead (e.g., `<div></div>`). Run `npx sv migrate self-closing-tags` to automate this fix.

Compile warning: svelte_element_invalid_this

The svelte_element_invalid_this warning is triggered when a string is used as the value of the `this` attribute on a `<svelte:element>`. Use an expression instead. Using a string attribute value will cause an error in future versions of Svelte.

Snippet type for snippet blocks

Snippet is a type representing a #snippet block. You can use it to express that your component expects a snippet of a certain type, for example: let { banner }: { banner: Snippet<[{ text: string }]> } = $props(). Snippets can only be called through the {@render ...} tag.

createRawSnippet to programmatically create snippets

createRawSnippet creates a snippet programmatically. It takes a function that receives getters for parameters and returns an object with a render() method that returns a string, and an optional setup() method that receives the Element and can return a cleanup function.

script_context_deprecated warning

The `script_context_deprecated` warning alerts that `context="module"` is deprecated and should be replaced with the `module` attribute instead.

element_invalid_self_closing_tag warning

The `element_invalid_self_closing_tag` warning alerts that self-closing HTML tags for non-void elements are ambiguous. Use `<%name% ...></%name%>` rather than `<%name% ... />`. The migration can be automated with `npx sv migrate self-closing-tags`.

element_implicitly_closed warning

The `element_implicitly_closed` warning alerts when an HTML element is implicitly closed by another element, which can cause an unexpected DOM structure. For example, a `<p>` inside another `<p>` will be implicitly closed. An explicit closing tag should be added to avoid ambiguity.

script_unknown_attribute warning

The `script_unknown_attribute` warning alerts when an unrecognized attribute is used on a script tag. Valid attributes are `generics`, `lang`, and `module`. If the attribute exists for a preprocessor, ensure the preprocessor removes it.

slot_snippet_conflict error

Cannot use `<slot>` syntax and `{@render ...}` tags in the same component. Must migrate towards `{@render ...}` tags completely.

snippet_invalid_export restriction

An exported snippet can only reference things declared in a `<script module>`, or other exportable snippets. It cannot reference things defined inside a non-module-level `<script>` block.

snippet_conflict error

Cannot use explicit children snippet at the same time as implicit children content. Remove either the non-whitespace content or the children snippet block.

Checking for slot content with $$slots conditional

To conditionally render content only when a specific slot is provided, use an {#if $$slots.slotName} block. For example, {#if $$slots.description} checks if the parent provided content for a slot named 'description', and only renders the contained HTML and slot if true.

Give your agent this brain