File: simple.md | Updated: 11/15/2025
Search...
+ K
Auto
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples GitHub Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Docs Examples Github Contributors
Maintainers Partners Support Learn StatsBETA Discord Merch Blog GitHub Ethos Brand Guide
Documentation
Framework
Svelte
Version
Latest
Search...
+ K
Menu
Getting Started
Guides
API Reference
Examples
Framework
Svelte
Version
Latest
Menu
Getting Started
Guides
API Reference
Examples
Svelte Example: Simple
====================================================================================================================================================================================================================================================================================================================================================================================================
Code ExplorerCode
Interactive SandboxSandbox
src
App.svelte
FieldInfo.svelte
main.ts
vite-env.d.ts
.gitignore
README.md
index.html
package.json
svelte.config.js
tsconfig.json
vite.config.ts
svelte
<script lang="ts">
import { createForm } from '@tanstack/svelte-form'
import FieldInfo from './FieldInfo.svelte'
const form = createForm(() => ({
defaultValues: {
firstName: '',
lastName: '',
employed: false,
jobTitle: '',
},
onSubmit: async ({ value }) => {
// Do something with form data
alert(JSON.stringify(value))
},
}))
</script>
<form
id="form"
onsubmit={(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}}
>
<h1>TanStack Form - Svelte Demo</h1>
<form.Field
name="firstName"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Not long enough' : undefined,
onChangeAsyncDebounceMs: 500,
onChangeAsync: async ({ value }) => {
await new Promise((resolve) => setTimeout(resolve, 1000))
return value.includes('error') && 'No "error" allowed in first name'
},
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>First Name</label>
<input
id={field.name}
type="text"
placeholder="First Name"
value={field.state.value}
onblur={() => field.handleBlur()}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
<form.Field
name="lastName"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Not long enough' : undefined,
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>Last Name</label>
<input
id={field.name}
type="text"
placeholder="Last Name"
value={field.state.value}
onblur={() => field.handleBlur()}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
<form.Field name="employed">
{#snippet children(field)}
<div>
<label for={field.name}>Employed?</label>
<input
oninput={() => field.handleChange(!field.state.value)}
checked={field.state.value}
onblur={() => field.handleBlur()}
id={field.name}
type="checkbox"
/>
</div>
{#if field.state.value}
<form.Field
name="jobTitle"
validators={{
onChange: ({ value }) =>
value.length === 0 ? 'If you have a job, you need a title' : null,
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>Job Title</label>
<input
type="text"
id={field.name}
placeholder="Job Title"
value={field.state.value}
onblur={field.handleBlur}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
{/if}
{/snippet}
</form.Field>
<div>
<form.Subscribe
selector={(state) => ({
canSubmit: state.canSubmit,
isSubmitting: state.isSubmitting,
})}
>
{#snippet children({ canSubmit, isSubmitting })}
<button type="submit" disabled={!canSubmit}>
{isSubmitting ? 'Submitting' : 'Submit'}
</button>
{/snippet}
</form.Subscribe>
<button
type="button"
id="reset"
onclick={() => {
form.reset()
}}
>
Reset
</button>
</div>
</form>
<script lang="ts">
import { createForm } from '@tanstack/svelte-form'
import FieldInfo from './FieldInfo.svelte'
const form = createForm(() => ({
defaultValues: {
firstName: '',
lastName: '',
employed: false,
jobTitle: '',
},
onSubmit: async ({ value }) => {
// Do something with form data
alert(JSON.stringify(value))
},
}))
</script>
<form
id="form"
onsubmit={(e) => {
e.preventDefault()
e.stopPropagation()
form.handleSubmit()
}}
>
<h1>TanStack Form - Svelte Demo</h1>
<form.Field
name="firstName"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Not long enough' : undefined,
onChangeAsyncDebounceMs: 500,
onChangeAsync: async ({ value }) => {
await new Promise((resolve) => setTimeout(resolve, 1000))
return value.includes('error') && 'No "error" allowed in first name'
},
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>First Name</label>
<input
id={field.name}
type="text"
placeholder="First Name"
value={field.state.value}
onblur={() => field.handleBlur()}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
<form.Field
name="lastName"
validators={{
onChange: ({ value }) =>
value.length < 3 ? 'Not long enough' : undefined,
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>Last Name</label>
<input
id={field.name}
type="text"
placeholder="Last Name"
value={field.state.value}
onblur={() => field.handleBlur()}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
<form.Field name="employed">
{#snippet children(field)}
<div>
<label for={field.name}>Employed?</label>
<input
oninput={() => field.handleChange(!field.state.value)}
checked={field.state.value}
onblur={() => field.handleBlur()}
id={field.name}
type="checkbox"
/>
</div>
{#if field.state.value}
<form.Field
name="jobTitle"
validators={{
onChange: ({ value }) =>
value.length === 0 ? 'If you have a job, you need a title' : null,
}}
>
{#snippet children(field)}
<div>
<label for={field.name}>Job Title</label>
<input
type="text"
id={field.name}
placeholder="Job Title"
value={field.state.value}
onblur={field.handleBlur}
oninput={(e: Event) => {
const target = e.target as HTMLInputElement
field.handleChange(target.value)
}}
/>
<FieldInfo {field} />
</div>
{/snippet}
</form.Field>
{/if}
{/snippet}
</form.Field>
<div>
<form.Subscribe
selector={(state) => ({
canSubmit: state.canSubmit,
isSubmitting: state.isSubmitting,
})}
>
{#snippet children({ canSubmit, isSubmitting })}
<button type="submit" disabled={!canSubmit}>
{isSubmitting ? 'Submitting' : 'Submit'}
</button>
{/snippet}
</form.Subscribe>
<button
type="button"
id="reset"
onclick={() => {
form.reset()
}}
>
Reset
</button>
</div>
</form>
