My new Nuxt module for doing amazing things.
- ⛰ Form handling similar to Inertia/Vue's useForm
- 🚠 Backend validation with Zod
- 🌲 Frontend form state management
- 🏔 Easy error handling and validation
Install the module to your Nuxt application with one command:
npx nuxi module add @louislschvn/nuxt-form
That's it! You can now use Nuxt Form in your Nuxt app ✨
Nuxt Form provides a utility function createValidationError
for easy backend validation:
import { createUserValidator } from '../validators'
export default defineEventHandler(async (event) => {
const result = await readValidatedBody(event, createUserValidator.safeParse)
if (!result.success) {
return createValidationError(result.error)
}
// Store in database..
return { statusCode: 201, message: 'success' }
})
On the frontend, you can use the useForm
composable to handle form state and submission:
<template>
<form @submit.prevent="submit">
<input v-model="form.email" type="text" placeholder="Enter your email">
<p v-if="form.errors.email">{{ form.errors.email }}</p>
<input v-model="form.password" type="password" placeholder="Enter your password">
<p v-if="form.errors.password">{{ form.errors.password }}</p>
<button type="submit" :disabled="form.processing">Submit</button>
</form>
<p v-if="success.state">Success!</p>
</template>
<script setup>
const form = useForm({
email: '',
password: '',
})
const success = ref({ state: false, message: '' })
const submit = async () => {
form.post('/api/endpoint', {
onError: (err) => {
form.reset('password')
console.warn(err)
},
onSuccess: (res) => {
success.value.state = true
success.value.message = res.message
form.reset()
},
})
}
</script>
This setup provides a seamless integration between frontend form handling and backend validation, similar to the functionality offered by Inertia.js and Vue's useForm, but tailored for Nuxt applications.
Nuxt Form also supports file uploads in a simple and efficient way. You can manage file uploads alongside your form data, and it even provides upload progress tracking.
In the example below, you can see how to add a file upload input to your form. The file selected will be sent with the rest of the form data when submitted.
<template>
<form @submit.prevent="submit">
<input
type="file"
@change="form.avatar = $event.target.files[0]"
>
<progress
v-if="form.progress"
:value="form.progress"
max="100"
>
{{ form.progress.percentage }}%
</progress>
<button
type="submit"
:disabled="form.processing"
>
Submit
</button>
</form>
</template>
<script setup>
const form = useForm({
avatar: null | File,
})
const submit = () => {
form.post('/api/endpoint')
}
</script>
- Automatically manage file uploads with the form data.
- Track upload progress with a visual progress bar.
- Handle file uploads
- Make success state natively available in the composable
Local development
# Install dependencies
npm install
# Generate type stubs
npm run dev:prepare
# Develop with the playground
npm run dev
# Build the playground
npm run dev:build
# Run ESLint
npm run lint
# Run Vitest
npm run test
npm run test:watch
# Release new version
npm run release