Forms are a common feature in web applications. They are used to collect user input and submit it to a server. However, it is important to validate form data before submitting it to ensure it is accurate and complete. We will show you how to create forms with validation in Next.js using Zod, React Hook Form, and Zod Resolver. For the UI parts of forms, we choose Shadcn which is not a component library but It's a collection of reusable components that you can copy and paste into your apps
What is Zod?
Zod is a powerful TypeScript validation library that provides a simple and intuitive way to define and validate data structures. It is designed to work seamlessly with TypeScript's type system, offering type safety and reducing the likelihood of runtime errors. Learn more
What is React Hook Form?
React Hook Form is a library that simplifies form handling in React by providing custom hooks and utility functions. It offers features such as controlled inputs, validation, and form submission. Learn more
What is Zod Resolver?
Zod Resolver is a utility library that integrates Zod schemas with React Hook Form, providing a seamless way to validate form data using Zod. Learn more
Create a new Next.js project or an existing Next.js project.
Install these packages
npm install react-hook-form
npm install zod
npm install @hookform/resolvers
Create a new component called basic-form.tsx which contains the form and inputs. We use Shadcn ui for the form elements. To get work of this basic form we have to install shadcn first and then form, input, and button. Like
npm install shadcn init
npm install form input button
"use client"
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"
export function BasicForm() {
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-2/3 space-y-6">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="Enter name" {...field} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder="Enter email" {...field} />
</FormControl>
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input type="password" placeholder="Enter Password" {...field} />
</FormControl>
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
Define a Zod schema for the form data.
const formSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
password: z.string().min(6),
})
Integrate the Zod schema with React Hook Form using Zod Resolver.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
name:'',
email:'example@gmail.com',
password:''
}
})
Add error messages to the form to display validation errors.
const formSchema = z.object({
name: z.string().min(2,{
message: "Name must be at least 2 characters.",
}),
email: z.string().email({
message: "Please enter a valid email address"
}),
password: z.string().min(6,{
message: "Password must be of 6 character"
}),
})
Submit the form and handle the response.
const onSubmit = (data: z.infer<typeof formSchema>) => {
console.log(data)
};
Here is the working example
https://codesandbox.io/p/devbox/zod-form-validation-vh9h9w
Conclusion
By leveraging Zod, Next.js, React Hook Form, Zod Resolver, and Shadcn, you can create robust, efficient, and visually appealing forms in your Next.js applications. This powerful combination provides a solid foundation for building high-quality user experiences.Thank you.
References
https://react-hook-form.com/docs/useform#resolver
https://react-hook-form.com/get-started
https://zod.dev/?id=introduction
https://www.freecodecamp.org/news/react-form-validation-zod-react-hook-form/
https://dev.to/majiedo/using-zod-with-react-hook-form-using-typescript-1mgk