sveltejs / sveltejs/kit

Regression: server action is not working from v2.43.0 if the submit button is a custom element when use:enhance is used

Open
#14,702 2 comments 1 reaction 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.