useNotForm
Creates and returns a fully typed, reactive form instance.
Signature
function useNotForm<TSchema extends ObjectSchema>(
config: UseNotFormConfig<TSchema>,
): NotFormInstance<TSchema>
Config
| Option | Type | Required | Description |
|---|---|---|---|
schema | MaybeRefOrGetter<TSchema> | Yes | Standard Schema compliant validation schema. Accepts a plain value, a ref, or a computed — resolved on every validation run. |
initialValues | DeepPartial<InferInput<TSchema>> | No | Starting values for the form. Deeply cloned on init — mutating the original after calling useNotForm has no effect. |
initialErrors | StandardSchemaV1.Issue[] | No | Errors to populate on creation. Useful when rendering server-side validation results on the initial load. |
validateOn | Partial<Record<ValidationTrigger, boolean>> | No | Which DOM events trigger field validation. Defaults: onBlur: true, onChange: true, onInput: true, everything else false. |
validationMode | 'eager' | 'lazy' | No | eager (default) — re-validates on input/change while an error exists. lazy — validates only on blur or submit. |
onSubmit | (values: InferOutput<TSchema>) => void | Promise<void> | No | Called after successful validation when the form is submitted. Receives the schema's validated output. Never called when validation fails. |
Return value — Values
| Property | Type | Description |
|---|---|---|
values | InferInput<TSchema> | Deeply reactive form values. Access directly with form.values.email — no .value needed. |
setValue(path, value) | method | Sets a value by dot-separated path without triggering validation. Use for programmatic updates or custom inputs. |
Return value — Touch
| Property | Type | Description |
|---|---|---|
touchedFields | Set<Paths<TInput>> | The set of field paths the user has interacted with. All paths are populated when the form is submitted. |
isTouched | ComputedRef<boolean> | true when at least one field has been touched. |
touchField(path) | method | Marks a field as touched. Called automatically by onBlur. |
Return value — Dirty
| Property | Type | Description |
|---|---|---|
dirtyFields | Set<Paths<TInput>> | The set of field paths whose current value differs from the initial value. |
isDirty | ComputedRef<boolean> | true when at least one field is dirty. |
dirtyField(path) | method | Marks a field as dirty. Called automatically when a value changes. |
Return value — Errors
| Property | Type | Description |
|---|---|---|
errors | StandardSchemaV1.Issue[] | The raw issues from the last validation run. |
errorsMap | ComputedRef<Partial<Record<Paths, string>>> | Flat map of field path to its first error message. Use for direct template access. |
setError(issue) | method | Replaces the existing error for the same path, or appends it if none exists. |
setErrors(issues) | method | Replaces all current errors at once. |
clearErrors() | method | Removes all active errors. |
getFieldErrors(path) | method | Returns all issues for a specific field path. |
Return value — Validation
| Property | Type | Description |
|---|---|---|
isValidating | Ref<boolean> | true while any validation run is in progress. |
validate() | method | Runs the full schema. Replaces all errors with the result. Check result.issues to determine pass/fail. |
validateField(path) | method | Runs the full schema but only updates errors for the given field. All other field errors are left untouched. |
isValid | ComputedRef<boolean> | true when there are no active errors. |
Return value — Submission
| Property | Type | Description |
|---|---|---|
submit(event) | method | Marks all fields as touched and dirty, validates the form, then calls onSubmit if validation passes. Calls event.preventDefault() when validation fails or when onSubmit is defined. Bind to @submit on <NotForm>. |
isSubmitting | Ref<boolean> | true while onSubmit is running. |
Return value — Reset
| Property | Type | Description |
|---|---|---|
reset(values?, errors?) | method | Restores the form to its initial state. Clears all errors, touched fields, and dirty fields. If values or errors are passed, they replace the stored baseline — the next call to reset() with no arguments returns to these new values. |
Examples
Reactive schema
const requireAddress = ref(false)
const schema = computed(() => z.object({
address: requireAddress.value
? z.string().min(1)
: z.string().optional(),
name: z.string().min(2),
}))
const form = useNotForm({ initialValues: { address: '', name: '' }, schema })
Server-side errors after submit
const form = useNotForm({
onSubmit: async (values) => {
try {
await $fetch('/api/signup', { body: values, method: 'POST' })
} catch {
form.setError({
message: 'This email is already registered',
path: [{ key: 'email' }],
})
}
},
schema,
})
Programmatic validation
// Full form
const result = await form.validate()
if (result.issues) {
console.log('Failed:', result.issues)
} else {
// Typed schema output
console.log('Output:', result.value)
}
// Single field
await form.validateField('email')