diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js
index 7207564ef9..84692fca9c 100644
--- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js
+++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js
@@ -11,6 +11,7 @@ import {
import { regex_starts_with_newline } from '../../../../patterns.js';
import * as b from '#compiler/builders';
import {
+ ELEMENT_IS_INPUT,
ELEMENT_IS_NAMESPACED,
ELEMENT_PRESERVE_ATTRIBUTE_CASE
} from '../../../../../../constants.js';
@@ -401,6 +402,8 @@ function build_element_spread_attributes(
flags |= ELEMENT_IS_NAMESPACED | ELEMENT_PRESERVE_ATTRIBUTE_CASE;
} else if (is_custom_element_node(element)) {
flags |= ELEMENT_PRESERVE_ATTRIBUTE_CASE;
+ } else if (element.type === 'RegularElement' && element.name === 'input') {
+ flags |= ELEMENT_IS_INPUT;
}
const object = build_spread_object(element, attributes, context);
diff --git a/packages/svelte/src/constants.js b/packages/svelte/src/constants.js
index 69cd213940..63324c860f 100644
--- a/packages/svelte/src/constants.js
+++ b/packages/svelte/src/constants.js
@@ -28,6 +28,7 @@ export const HYDRATION_ERROR = {};
export const ELEMENT_IS_NAMESPACED = 1;
export const ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;
+export const ELEMENT_IS_INPUT = 1 << 2;
export const UNINITIALIZED = Symbol();
diff --git a/packages/svelte/src/internal/server/index.js b/packages/svelte/src/internal/server/index.js
index 62ee22d6fc..5ccfb7ec8e 100644
--- a/packages/svelte/src/internal/server/index.js
+++ b/packages/svelte/src/internal/server/index.js
@@ -8,7 +8,8 @@ import { subscribe_to_store } from '../../store/utils.js';
import {
UNINITIALIZED,
ELEMENT_PRESERVE_ATTRIBUTE_CASE,
- ELEMENT_IS_NAMESPACED
+ ELEMENT_IS_NAMESPACED,
+ ELEMENT_IS_INPUT
} from '../../constants.js';
import { escape_html } from '../../escaping.js';
import { DEV } from 'esm-env';
@@ -187,6 +188,7 @@ export function spread_attributes(attrs, css_hash, classes, styles, flags = 0) {
const is_html = (flags & ELEMENT_IS_NAMESPACED) === 0;
const lowercase = (flags & ELEMENT_PRESERVE_ATTRIBUTE_CASE) === 0;
+ const ignore_defaults = (flags & ELEMENT_IS_INPUT) === 0;
for (name in attrs) {
// omit functions, internal svelte properties and invalid attribute names
@@ -200,6 +202,14 @@ export function spread_attributes(attrs, css_hash, classes, styles, flags = 0) {
name = name.toLowerCase();
}
+ if (!ignore_defaults) {
+ if (name === 'defaultvalue') {
+ name = 'value';
+ } else if (name === 'defaultchecked') {
+ name = 'checked';
+ }
+ }
+
attr_str += attr(name, value, is_html && is_boolean_attribute(name));
}
diff --git a/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/_config.js b/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/_config.js
new file mode 100644
index 0000000000..83a2575fbf
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/_config.js
@@ -0,0 +1,9 @@
+import { test } from '../../test';
+
+export default test({
+ mode: ['server'],
+ html: `
+
+
+`
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/main.svelte b/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/main.svelte
new file mode 100644
index 0000000000..5a17622bed
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/form-default-value-from-spread/main.svelte
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file