Skip to content

Conversation

@Rich-Harris
Copy link
Member

#14475 added a submitter option to myform.validate(...), but I'm not convinced it's the right move. Aside from feeling a bit clunky (you have to have a let submitter in your <script> together with a bind:this, it feels weird to say that a form's validity is dependent on which button the user ends up pressing, especially when we can't know that until they press it. While it is possible to construct a schema that's valid for one submitter but not another, it's very much not the norm: fields are typically valid or invalid in and of themselves.

And unlike <input> elements whose values change according to user input, <button> values are set by the developer. If they're invalid, it's a developer error rather than a user error.

Instead, I think we missed a trick: we should just include the default submitter (which, per WHATWG, is the first <button> inside the <form>) when constructing the FormData object.

The alternative would be to do both (include the default submitter and have an option for overriding it) but I really think that's just unnecessary API clutter.

cc @ottomated since you opened #14475


Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Edits

  • Please ensure that 'Allow edits from maintainers' is checked. PRs without this option may be closed.

…)` method, always provide default submitter
@changeset-bot
Copy link

changeset-bot bot commented Oct 20, 2025

🦋 Changeset detected

Latest commit: 8a67bb9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot
Copy link

@ottomated
Copy link
Contributor

ottomated commented Oct 20, 2025

I can see a case where the validity of a field could depend on which button you press, so I would vote for keeping it as an option (especially since it's already semi hidden inside an object parameter). I do think that defaulting to the first button / submit input is great though.

@Rich-Harris
Copy link
Member Author

'can see a case' as in you've encountered it/consider it a realistic outcome, or more of a hypothetical? All API surface area has a cost, so if it's the latter then I still vote for removal. I'm not even sure how you'd use such an option in practice.

@ottomated
Copy link
Contributor

I guess it's such a small likelyhood that it probably wouldn't come up realistically? The closest thing I've built is a media control form that has play/pause buttons as submitters, where you would have a case like "play is only valid if the current state is paused".

@teemingc
Copy link
Member

teemingc commented Oct 21, 2025

I agree with Ottomated. I talked about a realistic situation with my boss before where two buttons are needed and it’s when you have a “save as draft” and “publish” button. This is pretty common for our clients. It’s highly likely the form is always valid if you click the draft button but is stricter when clicking publish. I don’t know if you’d want different remote functions for the two actions when you can just slightly differ the logic depending on the submitter value.

Maybe it’s better to just pass the value of the button directly? This might make sense since we’re already manually passing in the submitter. Slightly more maintenance required if the button value changes but it’s less boilerplate. I agree the current API is clunky but I couldn’t think of a better way.

@Rich-Harris
Copy link
Member Author

How would you use it though? The form is either valid or invalid, and it's a state the form is in rather than a return value of validate() (necessarily), so when would you conditionally validate programmatically?

@teemingc
Copy link
Member

teemingc commented Oct 21, 2025

How the button value is useful in validation schemas

Personally, I've used Valibot's union to conditionally validate fields differently depending on the value of another field. This is probably how it will be used in the submitter value case too. Saving as draft means your requirements for most fields would be optional, but if the value is "publish", it would defer to the schema where fields are mandatory and it's great that TypeScript will reflect that the fields are definitely there in the return value of the remote function.

When programmatic validation would be used

If the main use case for programmatic validation is the "validate on input" feature, we probably also want this when there are "draft" and "publish" buttons. In this case, we most likely want it to "validate on input" using the draft validation schema which is less strict. To achieve that using a union of schemas, we would need a way to pass in the "draft" value for that submitter field and not the default submitter's value so that it knows it should use the draft validation schema.

@Rich-Harris
Copy link
Member Author

Another thing you could do, if making the 'publish as draft' button the default isn't possible: do the refinement inside the handler, using the invalid(...) API, once you know the action.

That's probably less nice than using submitter, in this case. Question is whether there are enough of these cases to make submitter the better trade-off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants