diff --git a/packages/svelte/src/internal/shared/attributes.js b/packages/svelte/src/internal/shared/attributes.js index 99a0b13d92..cb45af1839 100644 --- a/packages/svelte/src/internal/shared/attributes.js +++ b/packages/svelte/src/internal/shared/attributes.js @@ -261,5 +261,7 @@ export function to_style(value, styles) { return new_style === '' ? null : new_style; } - return value == null ? null : String(value); + // Empty results drop the attribute entirely so that client and SSR agree + // (the directive path above already returns `null` for empty output). + return value == null || value === '' ? null : String(value); } diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js index 59bcdeb7f5..7c64866995 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-attributes/_config.js @@ -12,8 +12,8 @@ export default test({ ` -

foo

-

foo

+

foo

+

foo

foo

` ); @@ -51,8 +51,8 @@ export default test({ ` -

foo

-

foo

+

foo

+

foo

foo

` ); diff --git a/packages/svelte/tests/runtime-runes/samples/style-update/_config.js b/packages/svelte/tests/runtime-runes/samples/style-update/_config.js index 52690a431a..347ed46c36 100644 --- a/packages/svelte/tests/runtime-runes/samples/style-update/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/style-update/_config.js @@ -37,14 +37,16 @@ export default test({ component.style = ''; flushSync(); + // empty results drop the attribute on both client and SSR (was previously + // `
` on the client only — a hydration mismatch) assert.htmlEqual( target.innerHTML, ` -
-
+
+
- - + + ` );