This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
# Releases
## svelte@5.51.0
### Minor Changes
- feat: Use `TrustedTypes` for HTML handling where supported
([#16271](https://github.com/sveltejs/svelte/pull/16271))
### Patch Changes
- fix: sanitize template-literal-special-characters in SSR attribute
values ([#17692](https://github.com/sveltejs/svelte/pull/17692))
- fix: follow-up formatting in `print()` — flush block-level elements
into separate sequences
([#17699](https://github.com/sveltejs/svelte/pull/17699))
- fix: preserve delegated event handlers as long as one or more root
components are using them
([#17695](https://github.com/sveltejs/svelte/pull/17695))
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Follow-up to #17319.
The `Fragment` visitor in `print()` only flushed sequences on
`RegularElement`, causing block-level elements (`Component`,
`SvelteHead`, `SvelteBoundary`, etc.) to be lumped into the same
sequence as adjacent nodes. This broke tools that programmatically
manipulate the AST (e.g.
[sveltejs/cli#915](https://github.com/sveltejs/cli/pull/915)).
The fix flushes before and after all block-level element types, ensuring
they get their own sequence and proper line separation.
### Before
```svelte
<svelte:head><title>Page Title</title></svelte:head><div>no space</div>
<Component /><Component />
<Component><span>child</span></Component><div>after component</div>
<svelte:boundary><div>boundary content</div></svelte:boundary><div>after boundary</div>
<!--comment--><div>after comment</div>
<div>before comment</div>
<!--comment-->
{#each items as item}
<div>{item}</div>
{/each}<div>after each</div>
{@render children()}<div>after render</div>
<div>before render</div>
{@render children()}
```
### After
```svelte
<svelte:head><title>Page Title</title></svelte:head>
<div>no space</div>
<Component />
<Component />
<Component><span>child</span></Component>
<div>after component</div>
<svelte:boundary><div>boundary content</div></svelte:boundary>
<div>after boundary</div>
<!--comment-->
<div>after comment</div>
<div>before comment</div>
<!--comment-->
{#each items as item}
<div>{item}</div>
{/each}
<div>after each</div>
{@render children()}
<div>after render</div>
<div>before render</div>
{@render children()}
```
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
Fixes#17694
Not really sure how to add a failing test here.
The code was generated by Codex 5.3, but I cleaned it up and manually
reviewed it myself. Not sure if this is the best approach to solving the
issue, though. It does add some overhead with the extra maps.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
As far as we can tell, there's no good way to turn off deployment
request notifications. This removes automatic pkg.pr.new builds for
commits not pushed directly to the svelte repository, meaning forks'
commits will have to be manually requested through the GitHub Actions
UI. It also makes the drive-by change of deriving the PR number from the
commit, which technically is a "breaking change" because there _could_
be multiple PRs associated with a commit... but let's just not do that
and we'll be okay.
### Before submitting the PR, please make sure you do the following
Resolves https://github.com/sveltejs/svelte/issues/14438
Resolves https://github.com/sveltejs/svelte/issues/10826
This PR makes it possible to use Svelte on pages which require
`TrustedTypes` support via their CSP by wrapping assignments to
`innerHTML` in a `TrustedTypePolicy` called `svelte-trusted-html` if the
`TrustedTypes` API exists.
Servers can allowlist the policy by setting `require-trusted-types-for
'script'; trusted-types svelte-trusted-html` in their
`Content-Security-Policy` header.
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
Note: I haven't run the tests since I don't have `pnpm` setup properly.
I have tested that:
1. A project with a CSP fails with Tip of Tree Svelte
2. That project works when installing this revision of Svelte
3. The project (with this revision) works in Browsers with no
`TrustedTypes` support (i.e. Firefox, Safari)
- [ ] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
My test project is here:
https://github.com/fallaciousreasoning/svelte-tt-test/blob/master/src/routes/%2Bpage.server.js
The only changes to the default project is adding the CSP in
`src/routes/page.server.js`
---------
Co-authored-by: 7nik <kfiiranet@gmail.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
Fixes a minor bug where HTML entities could be decoded into significant
characters in the template literal we output for SSR, leading to weird
effects. Not a security issue because it has to be literally written
into the svelte file you're compiling, but still wrong.
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Fixes#16342.
Errors thrown inside `$effect` were previously treated as
subtree-creation errors when `EFFECT_RAN === 0`, which caused them to be
rethrown instead of propagating to the nearest `<svelte:boundary>`. As a
result, `$effect` errors bypassed boundaries and appeared as uncaught
runtime errors. This change ensures that errors originating from effects
(`EFFECT`) are routed through `invoke_error_boundary`, allowing them to
bubble up the effect tree and be handled correctly by the closest
boundary. Existing subtree-creation behavior for non-effect cases
remains unchanged.
---
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
It should be the last piece of XHTML compliance.
We missed fixing `mutltiple` and `selected` attributes on `<select>` and
`<option>`.
Also, it seems the test runtime-legacy/select-multiple-spread was
broken.
I just copied to runtime-xhtml and updated tests that fail when a
`nodeName` comparison is broken. For `<progress>` no test due to JSDOM
quirks (at least in the past), and for `<template>` and `<script>`
nothing got broken 🤔
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This supersedes #16595, and fixes the issue by 'freezing' effects inside
deriveds when those deriveds are disconnected, and unfreezing them when
they reconnect. This is preferable to the current asymmetric behaviour
on `main` (in which effects are destroyed when the derived is
disconnected, and never recreated) and #16595, which causes the derived
itself to be re-evaluated.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
follow-up to #17418. This replaces every occurrence of
`document.createElement` with a helper, `create_element`, that delegates
to `document.createElementNS`. This makes the code a tiny bit simpler
and in theory should allow Svelte to run on `text/xml` documents, though
I'm not ready to add a test suite to prevent regressions for something
so niche.
If we choose to merge this, I think we can safely close#17418 as all
the other points (around case sensitivity etc) have already been taken
care of AFAICT.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [ ] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Tee Ming <chewteeming01@gmail.com>
Another XHTML thing, per
https://github.com/sveltejs/svelte/pull/17418#issuecomment-3863029273
(that PR doesn't address this issue)
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
## Summary
Fixes#13768
`<select bind:value={derived.prop}>` in legacy (non-runes) components
throws `effect_update_depth_exceeded` when the bound value comes from a
`$:` reactive statement.
**Root cause:** `setup_select_synchronization` created a
`template_effect` that called `invalidate_inner_signals`, which reads
and writes the same signals on every change — creating an infinite
update loop when those signals feed back into derived state.
**Fix:** Remove the effect-based synchronization entirely. Instead,
populate `legacy_indirect_bindings` during the analyze phase for
`<select bind:value>` elements, and call `invalidate_inner_signals`
inline at the mutation point in `AssignmentExpression` — only when the
binding is actually mutated, avoiding the read-write cycle.
Based on the approach outlined in #16200.
## Changes
- **`scope.js`**: Add `legacy_indirect_bindings` field to `Binding`
class
- **`RegularElement.js` (analyze)**: For `<select bind:value={foo}>`,
collect scope references as indirect bindings on the bound variable
- **`RegularElement.js` (transform)**: Remove
`setup_select_synchronization` function and its call site
- **`AssignmentExpression.js` (transform)**: When mutating a binding
with indirect bindings, append `invalidate_inner_signals` call after the
mutation
## Test plan
- Added `binding-select-reactive-derived` test that reproduces the exact
scenario from #13768
- All 3291 runtime-legacy tests pass (0 regressions)
- All 2312 runtime-runes tests pass
- All snapshot and compiler tests pass
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Currently, the [newly introduced `parseCss` from
`svelte/compiler`](https://github.com/sveltejs/svelte/pull/17496)
returns `Omit<AST.CSS.StyleSheet, 'attributes' | 'content'>`. If you try
to work with this in external tooling, everywhere where you pass around
the result of this method, you need to use that type as well, which is
quite cumbersome. (I'm trying to integrate this into `sv` to get rid of
a workaround)
This creates a new type in the CSS AST to differentiate between one
stylesheet only having the roles, and one beeing the full one that is
used in `parse` itself. Im 100% open on the name of the new type or any
better ideas.
### Before submitting the PR, please make sure you do the following
- [ ] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [ ] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
This was actually several bugs:
- We used `scopes` for the blockers, that's actually the template
scopes, should be `instance.scopes` instead
- We missed setting the scope for `touch`
- We didn't take return statements into account when calculating
blockers. We cannot know when/if something within the return statement
is called, so we gotta assume it is and touch everything transitively
from it
Combined this fixes#17667 (and possibly other cases not showing up in
the issue tracker yet)
Initially I just thought "ok I guess we have to traverse into functions,
too" but then I thought that feels too unoptimized and came up with the
return-statement-inspection, at which point I discovered the other bugs.
### Before submitting the PR, please make sure you do the following
- [x] It's really useful if your PR references an issue where it is
discussed ahead of time. In many cases, features are absent for a
reason. For large changes, please create an RFC:
https://github.com/sveltejs/rfcs
- [x] Prefix your PR title with `feat:`, `fix:`, `chore:`, or `docs:`.
- [x] This message body should clearly illustrate what problems it
solves.
- [x] Ideally, include a test that fails without this PR but passes with
it.
- [x] If this PR changes code within `packages/svelte/src`, add a
changeset (`npx changeset`).
### Tests and linting
- [x] Run the tests with `pnpm test` and lint the project with `pnpm
lint`
* chore: update ESLint to v10
Update eslint and related plugins/configs. Bump CI lint job to Node 24
(ESLint 10 requires ^20.19.0 || ^22.13.0 || >=24). Replace removed
Linter.FlatConfig type with Linter.Config.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address new `no-useless-assignment` violations from ESLint 10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* dedupe
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: reduce if block nesting
This reduces if block nesting similar to how we did it in #15250 (which got lost during the `await` feature introduction): If the if expression doesn't contain an await expression or is not dependent on a blocker that is not already resolved, then we can avoid creating a separate `$.if()` statement. The one trade-off is that we'll do re-invocations for all the conditions leading up to the condition that matches. Therefore non-simple if expressions are wrapper in `$.derived` to avoid excessive recomputations.
closes#17659 (~320 markers in prod mode possible now; less in dev because of our "wrap this component with devtime info" method)
helps with #15200
* tweak
* feedback
If the render tag is wrapped in `$.async`, that `$.async` call already contains surrounding markers, so we must not add our own to avoid hydration mismatches. Related to #17641, fixes#17225
* add xhtml tests
* unused
* tweak
* more tests
* tweak
* we don't need to actually check the HTML - if it's malformed in SSR or mount, it will throw
* same here
* unused, so we can revert this
* and this
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* docs: wrap JSDoc URLs in @see and @link tags
* fix: move curly brace to end of URL
* chore: add changeset
* add link text
* regenerate
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: allow NaN in key blocks
* lol whoops
* Update packages/svelte/src/internal/client/dom/blocks/key.js
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
* treat menu element like ul/ol for a11y role checks
The <menu> element has the same implicit role (list) as <ul> and <ol>,
so it should receive the same treatment in a11y checks:
- Allow <menu role="list"> without redundant role warning (CSS
list-style:none can remove semantics, role restores them)
- Allow <menu> with interactive roles like menu, menubar, radiogroup,
tablist, tree, treegrid (same exceptions as ul/ol)
Fixes#8529
* changeset
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Remove `onwheel` and `onmousewheel` from the list of passive events
in the v5 migration guide. Since #13322, only `ontouchstart` and
`ontouchmove` are passive by default, matching the basic-markup docs.
Closes#17430
* fix: exit resolved async blocks on correct node when hydrating
* expand test + fix
* tweak, add note to self
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
This is basically #17611, minus #17640, plus #17639. We need to add the $.next() call after render tags as well as components; rather than duplicating the logic, we can use is_standalone to determine when this is necessary (since this is what prevents $.append(...) from being used).
Fixes#17261Fixes#17608
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
creates a few abstractions in the compiler code around common "if-else" scenarios, as well as introducing a new runtime render helper
---------
Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com>
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
The store invalidation detection in each blocks only checked for
Identifier and MemberExpression AST node types. This caused bind:
on iteration variables to silently fail when the expression used
logical operators (e.g. `{#each $store.items ?? [] as item}`).
Use expression metadata dependencies instead of AST type checking
to find store_sub bindings, which correctly handles all expression
shapes.
Fixes#14625
* fix: emit `each_key_duplicate` error in production
* fix: preserve key
* Update packages/svelte/src/internal/client/dom/blocks/each.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Update packages/svelte/src/internal/client/dom/blocks/each.js
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: ensure keys are validated
* fix silly test name
* fix: cover other case of duplicate keys
* emit error on hydration
* ensure the error is handled
* drop useless tests
* unused
* finish merge
* add lost check back
* chore: bump playwright (#17565)
* chore: bump playwright
* maybe this will help somehow?
* err whatever
* fix
* chore: allow testing in production env 2 (#17590)
* Revert "chore: allow testing in production env (#16840)"
This reverts commit ffd65e90fe.
* new approach
* fix: handle renderer.run rejections (#17591)
* fix: handle renderer run rejections
* add test
* changeset
* simplify
* explanatory comment
---------
Co-authored-by: Antonio Bennett <abennett@mabelslabels.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* fix: only create async functions in SSR output when necessary (#17593)
* fix: only create async functions in SSR output when necessary
* actually...
* simplify generated code a bit more
* simplify
* fix: merge consecutive text nodes during hydration for large text content (#17587)
* fix: merge consecutive text nodes during hydration for large text content
Fixes#17582
Browsers automatically split text nodes exceeding 65536 characters into
multiple consecutive text nodes during HTML parsing. This causes hydration
mismatches when Svelte expects a single text node.
The fix merges consecutive text nodes during hydration by:
- Detecting when the current node is a text node
- Finding all consecutive text node siblings
- Merging their content into the first text node
- Removing the extra text nodes
This restores correct hydration behavior for large text content.
* add test, fix
* fix
* fix
* changeset
---------
Co-authored-by: Miner <miner@example.com>
Co-authored-by: Rich Harris <rich.harris@vercel.com>
* Version Packages (#17585)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Revert "drop useless tests"
This reverts commit 65f77ef840.
* update tests
* fix test
* we don't need to expose this function any more
* figured it out... we cant have errors during reconcile
* simplify
* tweak
* unused
* revert no-longer-needed change
* unused
---------
Co-authored-by: Rich Harris <rich.harris@vercel.com>
Co-authored-by: Antonio Bennett <31296212+Antonio-Bennett@users.noreply.github.com>
Co-authored-by: Antonio Bennett <abennett@mabelslabels.com>
Co-authored-by: FORMI <239411042+Richman018@users.noreply.github.com>
Co-authored-by: Miner <miner@example.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Remove SvelteKit data attributes from elements.d.ts
Removed SvelteKit specific data attributes from elements.d.ts.
* Remove SvelteKit data attributes from elements.d.ts
Removed SvelteKit data attributes from elements.d.ts.
---------
Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>