Quick start
A typed schema, validated inputs, a submit handler. The minimum viable form in five minutes.
- Time
- ~5 minutes
- You'll learn
- useForm + register + handleSubmit
Try the form below: clear the password and submit to watch focus pull to the broken field; submit with valid values to see the alert fire. Every behavior on screen comes from the Zod schema in code, which you'll see in the Build a form section next.
Build a form
Hand useForm a Zod schema and the reactive form comes back ready. This page reaches for three properties on the returned form: register for the input binding, handleSubmit for the submit gate, and fields for per-field error reads.
import { useForm } from 'attaform'
import { z } from 'zod'
const schema = z.object({
email: z.email('Enter a valid email'),
password: z.string().min(8, 'At least 8 characters'),
})
const form = useForm({ schema })
const onSubmit = form.handleSubmit(async (values) => {
await fetch('/api/sign-in', { method: 'POST', body: JSON.stringify(values) })
})
Bind inputs to schema paths with v-register:
<template>
<form @submit="onSubmit">
<label>
Email
<input v-register="form.register('email')" autocomplete="email" />
<em v-if="form.fields.email.showErrors">{{ form.fields.email.firstError?.message }}</em>
</label>
<label>
Password
<input v-register="form.register('password')" type="password" autocomplete="off" />
<em v-if="form.fields.password.showErrors">{{ form.fields.password.firstError?.message }}</em>
</label>
<button :disabled="form.meta.submitting" type="submit">Sign in</button>
</form>
</template>
form.register('email') returns what the v-register directive binds to. The directive handles the value read, the write, the coercion, and focus on invalid submit. Errors render via form.fields.<path>.firstError?.message, gated by form.fields.<path>.showErrors so the form doesn't yell on first paint.
What's next
- Your first schema: what Attaform reads from a Zod definition.
- The form: the full reactive surface returned by
useForm. - When validation runs: the moment errors appear.