Migration
Prerequisites
Before migrating:
- Follow the Installation guide to set up Nuxt Auto Form in your project.
- Have a basic understanding of the NuxtAutoForm component and its customization.
- Ensure Zod v4 is installed.
(Optional) Customize Your Default Config
If you already know that you have some default custom styles or components, update your app.config.ts before starting:
autoForm: {
submit: {
props: { label: 'Send form', class: 'w-full flex justify-center' },
},
},
Migration
Find your existing forms
Search for <UForm> in your codebase. Most editors support “search everywhere”:
Add AutoForm component
Inside the <template> near your <UForm> component, insert the AutoForm:
<AutoForm :schema="schema" @submit="onSubmit" />
Update your submit method
Update your onSubmit function to accept form data directly:
<script setup lang="ts">
import * as z from 'zod'
-type Schema = z.output<typeof schema>
const schema = z.object({
new_password: z.string()
})
-const state = reactive<Partial<Schema>>({
- new_password: undefined,
-})
-async function onSubmit(event: FormSubmitEvent<Schema>) {
+async function onSubmit(data: z.infer<typeof schema>) {
- event.preventDefault()
- console.log(event.data)
console.log(data)
}
Apply Customization Options
Now comes the fun part! You can make your form look exactly how you want using Customization options.
For most cases, simply add the meta attribute to your fields inside Zod schema.
const schema = z.object({
- new_password: z.string()
+ new_password: z.string().meta({ title: 'New account password', hint: 'Use at least 8 characters' })
})
And then if you need it, customize config property to the AutoForm component:
<AutoForm :schema="schema" @submit="onSubmit" :config="{ submit: { props: { label: 'Confirm' } } }" />
Remove Old UForm Component
We left the old <UForm> component temporarily so you can compare it with your new AutoForm and ensure everything works and looks correct.
Once you are confident the migration is complete, you can safely remove:
- The
<UForm>component from your templates - Any related state, imports, or helper code like
Schemaorstate
Good job! Repeat for all your UForms
Next steps
While you’re refactoring your forms, take a moment to explore Zod's Good Practices. Applying some of these practices can add auto imports, reduce code duplication and more.
Troubleshooting
This project is in Beta stage. There may be some bugs or missing features.
If you find something that doesn't work as expected or you are unsure how to migrate your form.
- Feel free to open a new GitHub issue.
- Chat with me on Discord (
@norbiros).
Examples
nuxt-auto-form, check out the Hack4KrakSite PR #637.<script setup lang="ts">
import * as z from 'zod'
-type Schema = z.output<typeof schema>
const schema = z.object({
- new_password: z.string()
+ new_password: z.string().meta({ title: 'New account password' })
})
-const loading = ref(false)
-const state = reactive<Partial<Schema>>({
- new_password: undefined,
-})
-async function onSubmit(event: FormSubmitEvent<Schema>) {
+async function onSubmit(data: z.infer<typeof schema>) {
- event.preventDefault()
- console.log(event.data)
console.log(data)
}
</script>
<template>
<div>
<h1 class="text-2xl font-medium">
Reset password
</h1>
- <UForm :schema="schema" :state="state" class="space-y-4 text-center" @submit="onSubmit">
- <UFormField label="New account password" name="new_password">
- <UInput v-model="state.new_password" class="w-full" />
- </UFormField>
- <div class="space-y-2">
- <UButton type="submit" class="w-full text-center inline rounded-3xl py-2 bg-neutral-300">
- Confirm
- </UButton>
- </div>
- </UForm>
+ <AutoForm :schema="schema" @submit="onSubmit" :config="{ submit: { props: { label: 'Confirm' } } }" />
</div>
</template>