From 579d0e663664d30c206ed955bbfbc396063dbad4 Mon Sep 17 00:00:00 2001 From: floriskn <48930050+floriskn@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:16:07 +0200 Subject: [PATCH] fix: ensure undefined attributes are removed during hydration (#16178) * fix: ensure undefined attributes are removed during hydration Attributes that are `undefined` on the client should be removed during hydration, even if their value hasn't changed compared to `prev_value`. * Create plenty-wasps-sleep.md * added test * Update .changeset/plenty-wasps-sleep.md --------- Co-authored-by: Rich Harris --- .changeset/plenty-wasps-sleep.md | 5 +++++ .../src/internal/client/dom/elements/attributes.js | 6 +++++- .../samples/removes-undefined-attributes/_config.js | 11 +++++++++++ .../removes-undefined-attributes/_expected.html | 1 + .../samples/removes-undefined-attributes/main.svelte | 9 +++++++++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .changeset/plenty-wasps-sleep.md create mode 100644 packages/svelte/tests/hydration/samples/removes-undefined-attributes/_config.js create mode 100644 packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html create mode 100644 packages/svelte/tests/hydration/samples/removes-undefined-attributes/main.svelte diff --git a/.changeset/plenty-wasps-sleep.md b/.changeset/plenty-wasps-sleep.md new file mode 100644 index 0000000000..aba96bc419 --- /dev/null +++ b/.changeset/plenty-wasps-sleep.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: remove undefined attributes on hydration diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index a663450b4a..2d3d6a921d 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -345,7 +345,11 @@ export function set_attributes(element, prev, next, css_hash, skip_warning = fal } var prev_value = current[key]; - if (value === prev_value) continue; + + // Skip if value is unchanged, unless it's `undefined` and the element still has the attribute + if (value === prev_value && !(value === undefined && element.hasAttribute(key))) { + continue; + } current[key] = value; diff --git a/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_config.js b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_config.js new file mode 100644 index 0000000000..bc74f23aac --- /dev/null +++ b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_config.js @@ -0,0 +1,11 @@ +import { test } from '../../test'; + +export default test({ + server_props: { + browser: false + }, + + props: { + browser: true + } +}); diff --git a/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html new file mode 100644 index 0000000000..cc789c8f51 --- /dev/null +++ b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/_expected.html @@ -0,0 +1 @@ +
diff --git a/packages/svelte/tests/hydration/samples/removes-undefined-attributes/main.svelte b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/main.svelte new file mode 100644 index 0000000000..1a587eeeeb --- /dev/null +++ b/packages/svelte/tests/hydration/samples/removes-undefined-attributes/main.svelte @@ -0,0 +1,9 @@ + + +