Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tanstack/form/llms.txt
Use this file to discover all available pages before exploring further.
Import
import { createForm } from '@tanstack/svelte-form'
Type
function createForm<TFormData>(
opts?: FormOptions<TFormData>
): SvelteFormApi<TFormData>
Parameters
Configuration options for the form. See FormOptions for details.
Initial values for the form fields
onSubmit
(values: { value: TFormData }) => void | Promise<void>
Handler called when the form is submitted
validators
FormValidators<TFormData>
Form-level validation functions
defaultState
Partial<FormState<TFormData>>
Initial state for the form
Returns
The form API object with the following properties and methods:
Svelte component for creating form fields
Function to create field instances programmatically
useStore
(selector?) => { current: TSelected }
Subscribe to form state with optional selector
Component for subscribing to form state
Current form state (reactive)
Method to handle form submission
Reset the form to its initial state
getFieldValue
<TField>(name: TField) => TValue
Get the current value of a field
setFieldValue
<TField>(name: TField, value: TValue) => void
Set the value of a field
validateAllFields
(cause: ValidationCause) => Promise<void>
Validate all fields in the form
Usage
Basic Example
<script lang="ts">
import { createForm } from '@tanstack/svelte-form'
const form = createForm({
defaultValues: {
firstName: '',
lastName: '',
age: 0,
},
onSubmit: async ({ value }) => {
console.log('Form submitted:', value)
},
})
</script>
<form
onsubmit={(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}}
>
<form.Field name="firstName">
{#snippet children({ field, state })}
<input
value={state.value}
onblur={field.handleBlur}
oninput={(e) => field.handleChange(e.currentTarget.value)}
/>
{/snippet}
</form.Field>
<button type="submit">Submit</button>
</form>
With Validation
<script lang="ts">
import { createForm } from '@tanstack/svelte-form'
const form = createForm({
defaultValues: {
email: '',
password: '',
},
onSubmit: async ({ value }) => {
// Handle login
console.log(value)
},
})
</script>
<form
onsubmit={(e) => {
e.preventDefault()
form.handleSubmit()
}}
>
<form.Field
name="email"
validators={{
onChange: ({ value }) => {
if (!value) return 'Email is required'
if (!value.includes('@')) return 'Invalid email'
return undefined
},
}}
>
{#snippet children({ field, state })}
<input
type="email"
value={state.value}
onblur={field.handleBlur}
oninput={(e) => field.handleChange(e.currentTarget.value)}
/>
{#if state.meta.errors.length > 0}
<em>{state.meta.errors[0]}</em>
{/if}
{/snippet}
</form.Field>
<form.Subscribe>
{#snippet children(state)}
<button type="submit" disabled={!state.canSubmit}>
{state.isSubmitting ? 'Submitting...' : 'Submit'}
</button>
{/snippet}
</form.Subscribe>
</form>
Subscribing to State
<script lang="ts">
import { createForm } from '@tanstack/svelte-form'
const form = createForm({
defaultValues: { name: '' },
onSubmit: async ({ value }) => console.log(value),
})
// Subscribe to specific state
const canSubmit = form.useStore((state) => state.canSubmit)
</script>
<div>
<p>Can Submit: {canSubmit.current}</p>
</div>
TypeScript
The form is fully typed based on your defaultValues:
interface FormData {
username: string
email: string
age: number
}
const form = createForm<FormData>({
defaultValues: {
username: '',
email: '',
age: 0,
},
onSubmit: async ({ value }) => {
// value is typed as FormData
console.log(value.username) // ✓ TypeScript knows this is a string
},
})
See Also