Description
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-test
anddata-direct
are present in the HTML, even though both are set toundefined
on 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
Metadata
Metadata
Assignees
Labels
No labels