Regression: server action is not working from v2.43.0 if the submit button is a custom element when use:enhance is used
Open
Nobody has claimed this yet.
forms
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
Server actions are not triggered if the submit button is a custom element. The error is occurring since v2.43.0.
# simple server action +page.server.ts
import { fail } from '@sveltejs/kit';
export const actions = {
default: async () => {
try {
console.log('Hello from server action');
return { message: "success" };
} catch (error) {
console.log(error);
return fail(500, { message: "error in server side" });
}
},
};
#+page.svelte with custom element definition
<script lang="ts">
import { onMount } from 'svelte';
import { applyAction, enhance } from '$app/forms';
import { goto } from '$app/navigation';
let mounted = $state(false);
onMount(async () => {
customElements.define('custom-button', class Button extends HTMLElement {
buttonBase: HTMLButtonElement;
constructor() {
super();
this.buttonBase = document.createElement("button");
this.buttonBase.style = "cursor: pointer";
this.buttonBase.append(document.createElement("slot"));
const shadow = this.attachShadow({ mode: "open", delegatesFocus: true });
shadow.append(this.buttonBase);
this.handleFormControl = () => {
const form = this.closest("form");
if (form && this.type) {
if (this.type === "reset") return form.reset();
else if (this.type === "submit") {
const event = new SubmitEvent("submit", {
submitter: this,
cancelable: true
});
form.reportValidity();
form.dispatchEvent(event);
setTimeout(() => {
if (event.defaultPrevented) return;
if (form.checkValidity()) form.submit();
});
}
}
}
}
connectedCallback() {
this.buttonBase.addEventListener("click", this.handleFormControl);
}
disconnectedCallback() {
this.buttonBase.removeEventListener("click", this.handleFormControl);
}
get type() {
return this.getAttribute('type');
}
set type(val) {
if (val) {
this.setAttribute('type', val);
} else {
this.removeAttribute('type');
}
}
});
mounted = true;
});
</script>
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://svelte.dev/docs/kit">svelte.dev/docs/kit</a> to read the documentation</p>
{#if mounted}
<form
novalidate={true}
method="POST"
use:enhance={() => {
return async ({ result }) => {
// `result` is an `ActionResult` object
if (result.type === 'redirect') {
goto(result.location);
} else {
await applyAction(result);
}
};
}}
>
<custom-button type="submit">
Submit
</custom-button>
</form>
{/if}
Reproduction
github repo
stackblitz
It was working with version: 2.42.0
Logs
client:733 [vite] connecting...
client:827 [vite] connected.
forms.js:139 Uncaught (in promise) TypeError: Failed to construct 'FormData': The specified element is not a submit button.
at HTMLFormElement.handle_submit (forms.js:139:21)
at Button.handleFormControl (+page.svelte:29:13)
handle_submit @ forms.js:139
Button.handleFormControl @ +page.svelte:29
System Info
System:
OS: Windows 10 10.0.19045
CPU: (8) x64 11th Gen Intel(R) Core(TM) i5-1145G7 @ 2.60GHz
Memory: 2.93 GB / 15.73 GB
Binaries:
Node: 22.14.0 - C:\Users\supab1\nodejs\node.EXE
npm: 11.4.1 - C:\Users\supab1\nodejs\npm.CMD
pnpm: 10.17.1 - C:\Users\supab1\AppData\Local\pnpm\pnpm.EXE
bun: 1.2.21 - C:\Users\supab1\.bun\bin\bun.EXE
Deno: 2.5.2 - C:\Users\supab1\.deno\bin\deno.EXE
Browsers:
Edge: Chromium (140.0.3485.54)
Firefox: 133.0.3 - C:\Program Files\Mozilla Firefox\firefox.exe
Internet Explorer: 11.0.19041.5794
npmPackages:
@sveltejs/adapter-node: ^5.3.2 => 5.3.3
@sveltejs/kit: ^2.46.4 => 2.46.4
@sveltejs/vite-plugin-svelte: ^6.2.0 => 6.2.1
svelte: ^5.39.5 => 5.39.11
vite: ^7.1.7 => 7.1.9
Severity
blocking an upgrade
Additional Information
This may be the button element is not having type=submit but this used to work earlier
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with forms.js around handle_submit at line 139 and reproduce the provided +page.svelte example using the linked repository or StackBlitz. Compare the behavior with version 2.42.0, then verify that a custom submit element used with use:enhance triggers the server action without the FormData TypeError.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100