OTP Field
One-time password input with individual character slots, powered by Base UI
An OTP field splits a one-time passcode across individual character slots, with paste and auto-advance handled for you. Use it for two-factor codes, email verification, or recovery codes.
Preview
Enter the 6-character code we sent to your device.
Installation
Usage
Composition
Examples
Alphanumeric
Set validationType="alphanumeric" to accept letters and numbers for recovery or backup codes.
Accept letters and numbers for backup codes such as A7C9XZ.
Grouped
Wrap inputs in OTPFieldGroup and place an OTPFieldSeparator between groups.
Placeholder Hints
Set placeholder on each OTPFieldInput to show a hint that hides when the slot is focused.
Placeholder hints stay visible until the active slot is focused.
Custom Sanitization
Restrict input to specific characters, with shake feedback on invalid input via the bundled useInvalidFeedback hook.
Digits 0-3 only.
Masked Entry
Set mask on OTPField to obscure entered characters for shared screens.
Use mask to obscure the code on shared screens.
Elevated Variant
On a Card, Dialog, or popover surface, the opaque default slots collapse into the parent. Use variant="elevated" on each OTPFieldInput for a translucent overlay that adapts to the substrate. See the Surfaces docs.
variant="elevated" on OTPFieldInput when the field sits inside a Card, Dialog, or popover.| Variant | Description |
|---|---|
default | Opaque bg-input slots for page-level surfaces. |
elevated | Translucent slots for use inside Card, Dialog, or popover. |
Form Integration
Use Field for labeling and form participation. See the Forms guide for more patterns.
API Reference
The OTP Field is built on top of Base UI's OTP Field. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.
For the complete Base UI API, see the Base UI OTP Field documentation.
Props
OTPField
Groups all OTP field parts and manages their state. Wraps Base UI's OTPField.Root. Renders a <div>.
No custom props. All Base UI Root props are passed through, including length, value, onValueChange, validationType, mask, normalizeValue, and onValueInvalid.
OTPFieldInput
Individual character input slot. Wraps Base UI's OTPField.Input. Renders an <input>.
OTPFieldSeparator
Visual separator between input groups. Wraps Base UI's Separator. Renders a <div>.
OTPFieldGroup
Layout wrapper for grouping inputs together. Not a Base UI component; renders a plain <div> with display: flex and gap.
Hooks
useInvalidFeedback
Manages shake animation and screen reader feedback for invalid OTP input. Bundled with the component, installed automatically when you install otp-field.
Wire its handlers to OTPField and its className getter to each OTPFieldInput:
Options
Returns
| Property | Type | Description |
|---|---|---|
handleValueChange | () => void | Clears invalid feedback. Wire to OTPField's onValueChange. |
handleValueInvalid | (value: string) => void | Triggers shake animation and status message. Wire to OTPField's onValueInvalid. |
getInvalidClassName | (index: number) => string | undefined | Returns the shake animation className for the active invalid slot, or undefined. |
setFocusedIndex | (index: number) => void | Tracks which slot is focused. Wire to each input's onFocus. |
statusMessage | string | Screen reader announcement. Render inside an aria-live="polite" region. |