Form
A native form element with consolidated error handling.
Anatomy
Form is composed together with Field. Import the components and place them together:
Examples
Submit with a Server Function
Forms can be submitted with a SvelteKit form action instead of onsubmit. Return the action's errors from fail() and pass them to errors. The demo below mimics the action with onFormSubmit. Connect a form action shows the real +page.server.ts and use:enhance.
Submit form values as a JavaScript object
You can use onFormSubmit instead of the native onsubmit to access form values as a JavaScript object. This is useful when you need to transform the values before submission, or integrate with 3rd party APIs.
When used, preventDefault is called on the native submit event.
Using with Zod
When parsing the schema using schema.safeParse(), the z.flattenError(result.error).fieldErrors data can be used to map the errors to each field's name. The demo below uses Valibot, where v.flatten(result.issues).nested gives the same shape.
API reference
A native form element with consolidated error handling. Renders a <form> element.
form S —
- Name
- Description
The external owner of form state, such as a SvelteKit remote form. Its attributes and attachment go on the
<form>. Fields bind to itsfields.- Type
S
enhance function —
- Name
- Description
Runs once the source has validated a submit, with the source's
enhancecontract. Callsubmit()to send it. Without this prop, a successful submit resets the form.- Type
(instance: EnhanceInstanceOf<S>) => unknown
validationMode FormValidationMode 'onSubmit'
- Name
- Description
When fields should validate. A
<Field.Root validationMode>takes precedence.- Type
FormValidationMode- Default
'onSubmit'
errors FormErrors —
- Name
- Description
Errors supplied from outside the form, usually after a server action. Use
bind:errorssoclearErrorscan drop a key. A new object from the parent replaces the current errors.- Type
FormErrors- Binding
bind:errors
onsubmit EventHandler<SubmitEvent, HTMLFormElement> | null —
- Name
- Description
Native submit listener. Runs after fields validate and only when no invalid field blocks the submit. Call
event.preventDefault()to keep the browser from navigating. This does not skiponFormSubmit.- Type
EventHandler<SubmitEvent, HTMLFormElement> | null
onFormSubmit function —
- Name
- Description
Called with each named field's value when submit is not blocked. The native submit is cancelled before this runs. With
form, the source submits instead, so useenhance.- Type
(formValues: FormValues, eventDetails: FormSubmitEventDetails) => void
onFocusInvalid function | Promise<void> —
- Name
- Description
Called in place of focusing the first invalid control, after a blocked submit or once errors or source issues arrive. Use it to reveal a control that is hidden, such as one on an inactive step. Form waits for the returned promise and the next DOM update, then focuses the control, also when the callback throws or rejects, unless focus moved while it ran. Keep a hidden step mounted, because a field that is not rendered does not register. With
novalidate={false}, the browser handles a native constraint before Form sees the submit, so this is not called for it.- Type
(detail: FormFocusInvalidDetail) => void | Promise<void>
novalidate boolean true
- Name
- Description
When true (the default), the browser's built-in constraint validation is off. Registered fields still validate through the form. It is set once the form is hydrated, so a page that has not loaded JavaScript keeps the browser's validation.
- Type
boolean- Default
true
render Snippet<[props: HTMLFormAttributes, state: FormState, children: Snippet | undefined]> —
- Name
- Description
Replace the default
<form>. Spreadpropsonto the host and renderchildren.- Type
Snippet<[props: HTMLFormAttributes, state: FormState, children: Snippet | undefined]>
Error
Messages no field shows: the source's root issues, issues on paths no mounted Field claims, and errors entries no registered Field has. Renders a <div> element. Sveltery addition with no Base UI counterpart. Before hydration only root issues render, because Fields later in the markup have not claimed their paths yet.
role AriaRole | null 'alert'
- Name
- Description
The host's role. Focus moves to no field when only form-level messages fail a submit, so the messages are announced.
- Type
AriaRole | null- Default
'alert'
children Snippet —
- Name
- Description
Replaces the messages.
- Type
Snippet
render Snippet<[props: HTMLAttributes<HTMLElement>, state: FormErrorState, children: Snippet | undefined]> —
- Name
- Description
Replace the default
<div>. Spreadpropsonto the host element.- Type
Snippet<[props: HTMLAttributes<HTMLElement>, state: FormErrorState, children: Snippet | undefined]>
transitionStatus 'starting' | 'ending' | 'idle' | undefined
- Name
transitionStatus- Description
The transition status of the error message.
- Type
'starting' | 'ending' | 'idle' | undefined