GitHub

useNotForm

Creates and returns a fully typed, reactive form instance.

Signature

function useNotForm<TSchema extends ObjectSchema>(
  config: UseNotFormConfig<TSchema>,
): NotFormInstance<TSchema>

Config

OptionTypeRequiredDescription
schemaMaybeRefOrGetter<TSchema>YesStandard Schema compliant validation schema. Accepts a plain value, a ref, or a computed — resolved on every validation run.
initialValuesDeepPartial<InferInput<TSchema>>NoStarting values for the form. Deeply cloned on init — mutating the original after calling useNotForm has no effect.
initialErrorsStandardSchemaV1.Issue[]NoErrors to populate on creation. Useful when rendering server-side validation results on the initial load.
validateOnPartial<Record<ValidationTrigger, boolean>>NoWhich DOM events trigger field validation. Defaults: onBlur: true, onChange: true, onInput: true, everything else false.
validationMode'eager' | 'lazy'Noeager (default) — re-validates on input/change while an error exists. lazy — validates only on blur or submit.
onSubmit(values: InferOutput<TSchema>) => void | Promise<void>NoCalled after successful validation when the form is submitted. Receives the schema's validated output. Never called when validation fails.

Return value — Values

PropertyTypeDescription
valuesInferInput<TSchema>Deeply reactive form values. Access directly with form.values.email — no .value needed.
setValue(path, value)methodSets a value by dot-separated path without triggering validation. Use for programmatic updates or custom inputs.

Return value — Touch

PropertyTypeDescription
touchedFieldsSet<Paths<TInput>>The set of field paths the user has interacted with. All paths are populated when the form is submitted.
isTouchedComputedRef<boolean>true when at least one field has been touched.
touchField(path)methodMarks a field as touched. Called automatically by onBlur.

Return value — Dirty

PropertyTypeDescription
dirtyFieldsSet<Paths<TInput>>The set of field paths whose current value differs from the initial value.
isDirtyComputedRef<boolean>true when at least one field is dirty.
dirtyField(path)methodMarks a field as dirty. Called automatically when a value changes.

Return value — Errors

PropertyTypeDescription
errorsStandardSchemaV1.Issue[]The raw issues from the last validation run.
errorsMapComputedRef<Partial<Record<Paths, string>>>Flat map of field path to its first error message. Use for direct template access.
setError(issue)methodReplaces the existing error for the same path, or appends it if none exists.
setErrors(issues)methodReplaces all current errors at once.
clearErrors()methodRemoves all active errors.
getFieldErrors(path)methodReturns all issues for a specific field path.

Return value — Validation

PropertyTypeDescription
isValidatingRef<boolean>true while any validation run is in progress.
validate()methodRuns the full schema. Replaces all errors with the result. Check result.issues to determine pass/fail.
validateField(path)methodRuns the full schema but only updates errors for the given field. All other field errors are left untouched.
isValidComputedRef<boolean>true when there are no active errors.

Return value — Submission

PropertyTypeDescription
submit(event)methodMarks 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>.
isSubmittingRef<boolean>true while onSubmit is running.

Return value — Reset

PropertyTypeDescription
reset(values?, errors?)methodRestores 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')