# Form > react-hook-form wiring with accessible errors. Import from `@aspyn-io/kit`. Scaffold source: `npx shadcn@latest add https://design.aspyn.io/r/form.json` ## Install ```tsx import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage, } from "@aspyn-io/kit"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; ``` ### Validated profile form react-hook-form + zod, with labels, descriptions, and errors wired for accessibility automatically (aria-describedby, aria-invalid, error announcement). Submit empty to see validation. ```tsx const schema = z.object({ display_name: z.string().min(2, "Display name must be at least 2 characters."), email: z.string().email("Enter a valid email address."), }); const form = useForm>({ resolver: zodResolver(schema), defaultValues: { display_name: "", email: "" }, });
( Display name Shown on your profile and in mentions. )} /> ``` ## Notes - FormControl works with any kit input via Slot: Input, Textarea, Select triggers, Checkbox, Switch. - Field names follow Aspyn API conventions: snake_case (display_name), so payloads map 1:1. - Install peer deps in your app: react-hook-form is bundled; add zod + @hookform/resolvers for schema validation.