Form with Validation
Wires react-hook-form and zod validation into the Input, Select, and Textarea primitives with accessible error messages tied to each field. Skip this and use plain Field and Label if the form has no validation rules to enforce.
Live preview
open in new tab ↗"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { Slot } from "radix-ui"
import { Controller, FormProvider, useFormContext, useFormState } from "react-hook-form"
import { Label } from "@/components/ui/label"
const Form = FormProvider
const FormFieldContext = React.createContext({})
function FormField(props) {
return (
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
)
}
function FormItem({ className, ...props }) {
const id = React.useId()
return <div data-slot="form-item" className={cn("grid gap-2", className)} {...props} />
}
function FormLabel({ className, ...props }) {
return <Label data-slot="form-label" className={cn("data-[error=true]:text-destructive", className)} {...props} />
}
function FormControl(props) {
return <Slot.Root data-slot="form-control" {...props} />
}
function FormMessage({ className, children, ...props }) {
if (!children) return null
return <p data-slot="form-message" className={cn("text-sm text-destructive", className)} {...props}>{children}</p>
}
export { Form, FormField, FormItem, FormLabel, FormControl, FormMessage }Block id: shadcn-formreact-tailwind · code-required
More form blocks
Want the whole site, not just the block?
We ship real client sites in 3 weeks — with blocks like this one, wired to your brand.



