Nuxt module
@notform/nuxt registers NotForm's public components and composable as Nuxt auto-imports. It does not change validation, field, or submission behavior. Every other page in these docs applies unchanged.
The module requires Nuxt 4 or later. For Vue or Vite applications, use the notform package.
Install and register
pnpm add @notform/nuxt zod
npm install @notform/nuxt zod
yarn add @notform/nuxt zod
bun add @notform/nuxt zod
export default defineNuxtConfig({
modules: ['@notform/nuxt'],
})
What is auto-imported
| Name | Kind |
|---|---|
useForm | Composable |
Form | Component |
Field | Component |
ArrayField | Component |
FieldError | Component |
Your schema library is not auto-imported. Import it as usual.
<script setup lang="ts">
import { z } from 'zod'
const form = useForm({
initialValues: { email: '' },
onSubmit(data) {
console.log(data.email)
},
schema: z.object({
email: z.email('Enter a valid email address.')
}),
})
</script>
<template>
<Form :form="form">
<Field
v-slot="{ field }"
:field="form.field('email')"
>
<label :for="field.path">Email</label>
<input
:id="field.path"
v-model="field.model"
v-bind="field.events"
type="email"
>
<FieldError :errors="field" />
</Field>
<button type="submit">
Submit
</button>
</Form>
</template>
Import types
Types are not auto-imported. To import them, add notform as a direct dependency of your app. Package managers such as pnpm do not expose a module's own dependencies to your code.
pnpm add notform
import type { SchemaInput, SchemaOutput, UseFormInstance } from 'notform'
The same applies if you prefer explicit imports of components or useForm over auto-imports. Both approaches work together.
Avoid name conflicts
If your app, or another module, already defines Form, Field, FieldError, ArrayField, or useForm, register NotForm's version under another name with the aliases option. Add only the aliases you need.
export default defineNuxtConfig({
modules: ['@notform/nuxt'],
notform: {
aliases: {
Field: 'NotField',
FieldError: 'NotFieldError',
Form: 'AppForm',
useForm: 'useAppForm',
},
},
})
Then use the alias everywhere:
<template>
<AppForm :form="form">
<NotField
v-slot="{ field }"
:field="form.field('email')"
>
<NotFieldError :errors="field" />
</NotField>
</AppForm>
</template>
Keys are the original NotForm names. Values are the names you want to use.
Field or FieldError, such as ShadcnVue, are the most common source of conflicts. See ShadcnVue.Server-side rendering
NotForm creates form state during setup and does not need browser APIs to do it, so forms render on the server. Validation timers and event handlers only run in the browser, in response to user interaction.
Next steps
- Build your first form with the Quickstart.
- Use NotForm with Nuxt UI in the Nuxt UI guide.