Form
Forms contain fields of controls to enter information for submission.
Installation
Base UI components are all available as a single package.
npm install @base_ui/react
Once you have the package installed, import the component.
import { Form } from '@base_ui/react/Form';
import { Field } from '@base_ui/react/Field';Anatomy
Forms are implemented using a Root component and Field components:
<Form.Root />renders the<form>element.<Field.Root />renders an individual Field element.
<Form.Root>
<Field.Root />
</Form.Root>Usage
Forms are intended to be used with the Field component, which provides labeling and validation for individual form controls. These are nested inside Form.Root:
import { Form } from '@base_ui/react/Form';
import { Field } from '@base_ui/react/Field';<Form.Root>
<Field.Root>
<Field.Control />
</Field.Root>
<button type="submit">Submit</button>
</Form.Root>If any of the Fields within the Form are invalid upon submit, focus is moved to the first invalid Field's control and the submit event is prevented.
Validation
The Field.Error subcomponent of a Field renders error messages inside of it, with its content automatically populated with any client-side validation messages that occur.
<Field.Root>
<Field.Control />
<Field.Error />
</Field.Root>Server-side validation
For server-side validation messages, the Form.Root component accepts an errors prop — an object whose keys map to the Field name prop, with each value being a string or array of strings representing error messages. The onClearErrors prop is called to clear these external server errors when the field's control has been changed:
const [errors, setErrors] = React.useState({});
async function handleSubmit(event) {
event.preventDefault();
const formData = Object.fromEntries(new FormData(event.currentTarget));
try {
await submitForm(formData);
} catch (errors) {
// Map errors from the server response
setErrors({
username: errors.username,
});
}
}
return (
<Form.Root onSubmit={handleSubmit} errors={errors} onClearErrors={setErrors}>
<Field.Root name="username">
<Field.Control />
<Field.Error /> {/* Populated with `errors.username` string */}
</Field.Root>
</Form.Root>
);For more flexibility if required, each Field.Root component accepts an invalid boolean prop, and each Field.Error subcomponent accepts a forceShow boolean prop. These can be used as an alternative to Form.Root's errors prop by manually targeting specific Fields and showing specific error messages.
Native validation
By default, browser-native validation popups are disabled, as Field.Error replaces this by rendering the validation messages to allow for flexible styling. If necessary, to enable these native validation popups, re-apply the default prop:
<Form.Root noValidate={false}>API Reference
FormRoot
| Prop | Type | Default | Description |
|---|---|---|---|
className | union | Class names applied to the element or a function that returns them based on the component's state. | |
errors | object | Object of error messages with each key mapping to the name prop of a Field control, usually from server-side validation. | |
onClearErrors | func | Callback fired when the external server-side error messages should be cleared. | |
render | union | A function to customize rendering of the component. |