fix: ensure undefined attributes are removed during hydration
#16178
Closing issue
Describe the bug
When using SvelteKit with SSR, attributes that are set to an empty string on the server and undefined on the client (either via spread or direct bindings) are not removed during hydration. This results in mismatched DOM expectations, where data-* attributes persist even though their value becomes undefined on the client.
This behavior affects both spread attributes ({...map}) and direct bindings (data-test={value}), making it difficult to conditionally render and remove attributes correctly across server/client boundaries.
Reproduction
Repo: https://github.com/floriskn/sveltekit-attribute-mismatch
Steps to reproduce:
- Clone the repo and run the dev server
- Inspect the rendered
<p>element in the browser - Observe that
data-testanddata-directare present in the HTML, even though both are set toundefinedon the client
Example code from the repo:
<script lang="ts">
import { browser } from "$app/environment";
let attributeMap = {
"data-test": browser ? undefined : ""
};
let directValue = browser ? undefined : "";
</script>
<p {...attributeMap} data-direct={directValue}>
Inspect this element
</p>
Logs
System Info
System:
OS: Windows 10 10.0.19045
CPU: (16) x64 Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
Memory: 12.30 GB / 31.92 GB
Binaries:
Node: 20.11.1 - C:\Program Files\nodejs\node.EXE
npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD
pnpm: 9.15.0 - ~\AppData\Local\pnpm\pnpm.EXE
Browsers:
Edge: Chromium (127.0.2651.105)
Internet Explorer: 11.0.19041.5794
npmPackages:
@sveltejs/adapter-auto: ^6.0.0 => 6.0.1
@sveltejs/kit: ^2.16.0 => 2.21.5
@sveltejs/vite-plugin-svelte: ^5.0.0 => 5.1.0
svelte: ^5.0.0 => 5.34.3
vite: ^6.2.6 => 6.3.5
Severity
serious, but I can work around it
Additional Information
No response
Pull request
Attributes set server-side but undefined on the client should be removed during hydration. This ensures expected cleanup behavior and resolves a mismatch between SSR and client-side rendering.
Fixes #16184
Info
🦋 Changeset detected
Latest commit: 574def1
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 1 package
| Name | Type |
|---|---|
| svelte | Patch |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
Please, add a test that fails without this fix. Propably it should go to the hydration folder, you can at the input-value-changed test as example of what you need.
I’ve added the test under hydration named removes-undefined-attributes. It will fail without the fix, confirming the issue is properly covered.
pnpm add https://pkg.pr.new/svelte@16178Attributes that are `undefined` on the client should be removed during hydration, even if their value hasn't changed compared to `prev_value`.
Pro tip: You can prefix GitHub URLs of issues, PRs or discussions with svcl.dev/ to view them on this page! Also try it on a GitHub release ;)