@ -102,3 +102,40 @@ If an `onerror` function is provided, it will be called with the same two `error
```
If an error occurs inside the `onerror` function (or if you rethrow the error), it will be handled by a parent boundary if such exists.
## Using `transformError`
By default, error boundaries have no effect on the server — if an error occurs during rendering, the render as a whole will fail.
Since 5.51 you can control this behaviour for boundaries with a `failed` snippet, by calling [`render(...)`](imperative-component-api#render) with a `transformError` function.
> [!NOTE] If you're using Svelte via a framework such as SvelteKit, you most likely don't have direct access to the `render(...)` call — the framework must configure `transformError` on your behalf. SvelteKit will add support for this in the near future, via the [`handleError`](../kit/hooks#Shared-hooks-handleError) hook.
The `transformError` function must return a JSON-stringifiable object which will be used to render the `failed` snippet. This object will be serialized and used to hydrate the snippet in the browser:
```js
// @errors: 1005
import { render } from 'svelte/server';
import App from './App.svelte';
const { head, body } = await render(App, {
transformError: (error) => {
// log the original error, with the stack trace...
console.error(error);
// ...and return a sanitized user-friendly error
// to display in the `failed` snippet
return {
message: 'An error occurred!'
};
};
});
```
If `transformError` throws (or rethrows) an error, `render(...)` as a whole will fail with that error.
> [!NOTE] Errors that occur during server-side rendering can contain sensitive information in the `message` and `stack`. It's recommended to redact these rather than sending them unaltered to the browser.
If the boundary has an `onerror` handler, it will be called upon hydration with the deserialized error object.
The [`mount`](imperative-component-api#mount) and [`hydrate`](imperative-component-api#hydrate) functions also accept a `transformError` option, which defaults to the identity function. As with `render`, this function transforms a render-time error before it is passed to a `failed` snippet or `onerror` handler.
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [actions](use) on `document`.
Similarly to `<svelte:window>`, this element allows you to add listeners to events on `document`, such as `visibilitychange`, which don't fire on `window`. It also lets you use [attachments](@attach) on `document`.
As with `<svelte:window>`, this element may only appear the top level of your component and must never be inside a block or element.
@ -75,7 +75,7 @@ In both cases, a `svelte.config.js` with `vitePreprocess` will be added. Vite/Sv
### Other build tools
If you're using tools like Rollup or Webpack instead, install their respective Svelte plugins. For Rollup that's [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) and for Webpack that's [svelte-loader](https://github.com/sveltejs/svelte-loader). For both, you need to install `typescript` and `svelte-preprocess` and add the preprocessor to the plugin config (see the respective READMEs for more info). If you're starting a new project, you can also use the [rollup](https://github.com/sveltejs/template) or [webpack](https://github.com/sveltejs/template-webpack) template to scaffold the setup from a script.
If you're using tools like Rollup or Webpack instead, install their respective Svelte plugins. For Rollup that's [rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte) and for Webpack that's [svelte-loader](https://github.com/sveltejs/svelte-loader). For both, you need to install `typescript` and `svelte-preprocess` and add the preprocessor to the plugin config (see the respective READMEs for more info).
> [!NOTE] If you're starting a new project, we recommend using SvelteKit or Vite instead
@ -682,6 +682,24 @@ Previously, Svelte employed a very complicated algorithm to determine if whitesp
- Whitespace between nodes is collapsed to one whitespace
- Whitespace at the start and end of a tag is removed completely
This new behavior is slightly different from native HTML rendering. For example, `<p>foo<span> - bar</span></p>` will render:
- `foo - bar` in HTML
- `foo- bar` in Svelte 5
You can reintroduce the missing space by moving it outside the `<span>`...
```svelte
<p>foo <span>- bar</span></p>
```
...or, if necessary for styling reasons, including it as an expression:
```svelte
<p>foo<span>{' '}- bar</span></p>
```
- Certain exceptions apply such as keeping whitespace inside `pre` tags
As before, you can disable whitespace trimming by setting the `preserveWhitespace` option in your compiler settings or on a per-component basis in `<svelte:options>`.
@ -62,6 +62,14 @@ Keyed each block has duplicate key at indexes %a% and %b%
Keyed each block has duplicate key `%value%` at indexes %a% and %b%
```
### each_key_volatile
```
Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item
```
The key expression in a keyed each block must return the same value when called multiple times for the same item. Using expressions like `[item.a, item.b]` creates a new array each time, which will never be equal to itself. Instead, use a primitive value or create a stable key like `item.a + '-' + item.b`.
@ -63,9 +63,29 @@ Event attribute must be a JavaScript expression, not a string
### attribute_invalid_sequence_expression
```
Sequence expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
Comma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
```
An attribute value cannot be a comma-separated sequence of expressions —in other words this is disallowed:
```svelte
<divclass={size,color}>...</div>
```
Instead, make sure that the attribute value contains a single expression. In the example above it's likely that this was intended (see the [class documentation](class) for more details):
```svelte
<divclass={[size,color]}>...</div>
```
If you _do_ need to use the comma operator for some reason, wrap the sequence in parentheses:
```svelte
<divclass={(size,color)}>...</div>
```
Note that this will evaluate to `color`, ignoring `size`.
@ -16,6 +16,14 @@ Encountered asynchronous work while rendering synchronously.
You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.
### dynamic_element_invalid_tag
```
`<svelte:element this="%tag%">` is not a valid element name — the element will not be rendered
```
The value passed to the `this` prop of `<svelte:element>` must be a valid HTML element, SVG element, MathML element, or custom element name. A value containing invalid characters (such as whitespace or special characters) was provided, which could be a security risk. Ensure only valid tag names are passed.
- fix: escape `innerText` and `textContent` bindings of `contenteditable` ([`0df5abcae223058ceb95491470372065fb87951d`](https://github.com/sveltejs/svelte/commit/0df5abcae223058ceb95491470372065fb87951d))
- fix: sanitize `transformError` values prior to embedding in HTML comments ([`0298e979371bb583855c9810db79a70a551d22b9`](https://github.com/sveltejs/svelte/commit/0298e979371bb583855c9810db79a70a551d22b9))
## 5.53.4
### Patch Changes
- fix: set server context after async transformError ([#17799](https://github.com/sveltejs/svelte/pull/17799))
- fix: hydrate if blocks correctly ([#17784](https://github.com/sveltejs/svelte/pull/17784))
- fix: re-run non-render-bound deriveds on the server ([#17674](https://github.com/sveltejs/svelte/pull/17674))
## 5.51.5
### Patch Changes
- fix: check to make sure `svelte:element` tags are valid during SSR ([`73098bb26c6f06e7fd1b0746d817d2c5ee90755f`](https://github.com/sveltejs/svelte/commit/73098bb26c6f06e7fd1b0746d817d2c5ee90755f))
- fix: misc option escaping and backwards compatibility ([#17741](https://github.com/sveltejs/svelte/pull/17741))
- fix: strip event handlers during SSR ([`a0c7f289156e9fafaeaf5ca14af6c06fe9b9eae5`](https://github.com/sveltejs/svelte/commit/a0c7f289156e9fafaeaf5ca14af6c06fe9b9eae5))
- fix: replace usage of `for in` with `for of Object.keys` ([`f89c7ddd7eebaa1ef3cc540400bec2c9140b330c`](https://github.com/sveltejs/svelte/commit/f89c7ddd7eebaa1ef3cc540400bec2c9140b330c))
- fix: always escape option body in SSR ([`f7c80da18c215e3727c2a611b0b8744cc6e504c5`](https://github.com/sveltejs/svelte/commit/f7c80da18c215e3727c2a611b0b8744cc6e504c5))
@ -42,6 +42,12 @@ See the [migration guide](/docs/svelte/v5-migration-guide#Components-are-no-long
> Keyed each block has duplicate key `%value%` at indexes %a% and %b%
## each_key_volatile
> Keyed each block has key that is not idempotent — the key for item at index %index% was `%a%` but is now `%b%`. Keys must be the same each time for a given item
The key expression in a keyed each block must return the same value when called multiple times for the same item. Using expressions like `[item.a, item.b]` creates a new array each time, which will never be equal to itself. Instead, use a primitive value or create a stable key like `item.a + '-' + item.b`.
## effect_in_teardown
> `%rune%` cannot be used inside an effect cleanup function
> Sequence expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
> Comma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses
An attribute value cannot be a comma-separated sequence of expressions —in other words this is disallowed:
```svelte
<divclass={size,color}>...</div>
```
Instead, make sure that the attribute value contains a single expression. In the example above it's likely that this was intended (see the [class documentation](class) for more details):
```svelte
<divclass={[size,color]}>...</div>
```
If you _do_ need to use the comma operator for some reason, wrap the sequence in parentheses:
```svelte
<divclass={(size,color)}>...</div>
```
Note that this will evaluate to `color`, ignoring `size`.
@ -10,6 +10,12 @@ Some platforms require configuration flags to enable this API. Consult your plat
You (or the framework you're using) called [`render(...)`](svelte-server#render) with a component containing an `await` expression. Either `await` the result of `render` or wrap the `await` (or the component containing it) in a [`<svelte:boundary>`](svelte-boundary) with a `pending` snippet.
## dynamic_element_invalid_tag
> `<svelte:element this="%tag%">` is not a valid element name — the element will not be rendered
The value passed to the `this` prop of `<svelte:element>` must be a valid HTML element, SVG element, MathML element, or custom element name. A value containing invalid characters (such as whitespace or special characters) was provided, which could be a security risk. Ensure only valid tag names are passed.
## html_deprecated
> The `html` property of server render results has been deprecated. Use `body` instead.
e(node,'attribute_invalid_sequence_expression',`Sequence expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses\nhttps://svelte.dev/e/attribute_invalid_sequence_expression`);
e(node,'attribute_invalid_sequence_expression',`Comma-separated expressions are not allowed as attribute/directive values in runes mode, unless wrapped in parentheses\nhttps://svelte.dev/e/attribute_invalid_sequence_expression`);
consterror=newError(`each_key_volatile\nKeyed each block has key that is not idempotent — the key for item at index ${index} was \`${a}\` but is now \`${b}\`. Keys must be the same each time for a given item\nhttps://svelte.dev/e/each_key_volatile`);
consterror=newError(`dynamic_element_invalid_tag\n\`<svelte:element this="${tag}">\` is not a valid element name — the element will not be rendered\nhttps://svelte.dev/e/dynamic_element_invalid_tag`);