Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex.
Well-designed HTML forms are:
- Well-structured and semantically correct.
- Easy to use and navigate (keyboard).
- Accessible with ARIA attributes and proper labels.
- Has support for client and server side validation.
- Well-styled and consistent with the rest of the application.
In this guide, we will take a look at building forms with react-hook-form
and zod
. We're going to use a <FormField>
component to compose accessible forms using Radix UI components.
Features
The <Form />
component is a wrapper around the react-hook-form
library. It provides a few things:
- Composable components for building forms.
- A
<FormField />
component for building controlled form fields. - Form validation using
zod
. - Handles accessibility and error messages.
- Uses
React.useId()
for generating unique IDs. - Applies the correct
aria
attributes to form fields based on states. - Built to work with all Radix UI components.
- Bring your own schema library. We use
zod
but you can use anything you want. - You have full control over the markup and styling.
Anatomy
Example
Installation
Usage
Create a form schema
Define the shape of your form using a Zod schema. You can read more about using Zod in the Zod documentation.
Define a form
Use the useForm
hook from react-hook-form
to create a form.
Since FormField
is using a controlled component, you need to provide a default value for the field. See the React Hook Form docs to learn more about controlled components.
Build your form
We can now use the <Form />
components to build our form.
Done
That's it. You now have a fully accessible form that is type-safe with client-side validation.
Examples
See the following links for more examples on how to use the <Form />
component with other components: