Input OTP
A one-time password input component for React and Next.js. Perfect for 2FA authentication, verification codes, and secure login flows with shadcn/ui styling.
Ever tried to type a 6-digit code into separate boxes and wanted to throw your phone? This OTP input actually works the way users expect - cursor jumps automatically, paste works, no fighting with focus.
2FA verification input
Clean, accessible OTP input with automatic focus handling:
Built on input-otp by @guilherme_rodz, styled with Tailwind, and ready to drop into any Next.js auth flow.
npx shadcn@latest add input-otp
Why good OTP inputs matter
You know those OTP inputs where you have to click each box manually? Yeah, this isn't one of those. Type a digit, cursor moves automatically. Copy-paste a code, it fills in all the boxes. Mobile keyboard shows numbers. It just works.
OTP patterns that users actually like
Simple 4-digit PIN
Simple PIN entry:
6-digit with separator
The classic SMS code layout:
Custom patterns
Letters and numbers for backup codes:
Multiple separators
When you need more visual grouping:
Controlled with feedback
Show users what they're typing:
Form integration
Proper form validation:
Built for Next.js auth flows
Works with whatever auth setup you've got - NextAuth.js, Clerk, Auth0, doesn't matter. Hook up the onChange
and you're good to go.
API Reference
InputOTP
The root component that manages the OTP input state and behavior.
Prop | Type | Default | Description |
---|---|---|---|
maxLength | number | 6 | Maximum number of characters |
value | string | - | Controlled input value |
onChange | (value: string) => void | - | Change handler for controlled usage |
onComplete | (value: string) => void | - | Called when all slots are filled |
pattern | RegExp | REGEXP_ONLY_DIGITS | Regex pattern for valid characters |
disabled | boolean | false | Whether the input is disabled |
autoFocus | boolean | false | Auto-focus the first slot on mount |
children | React.ReactNode | - | InputOTPGroup and InputOTPSeparator components |
InputOTPGroup
Container for grouping OTP slots together visually.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
children | React.ReactNode | - | InputOTPSlot components |
InputOTPSlot
Individual character input slot within the OTP.
Prop | Type | Default | Description |
---|---|---|---|
index | number | - | Position index in the OTP sequence |
className | string | - | Additional CSS classes |
InputOTPSeparator
Visual separator between groups of OTP slots.
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | Additional CSS classes |
Common Patterns
Pattern | RegExp | Use Case |
---|---|---|
Numbers only | REGEXP_ONLY_DIGITS | SMS codes, PIN numbers |
Numbers + Letters | REGEXP_ONLY_DIGITS_AND_CHARS | Backup codes, complex tokens |
Custom | Your own RegExp | Specific format requirements |
Keyboard Interactions
Key | Action |
---|---|
0-9 , A-Z | Enter character (if pattern allows) |
Backspace | Delete current character, move to previous |
Delete | Clear current character |
Arrow Left/Right | Navigate between slots |
Tab | Move to next focusable element |
Shift + Tab | Move to previous focusable element |
Ctrl/Cmd + V | Paste and auto-fill slots |
Accessibility Features
Feature | Implementation |
---|---|
Screen Readers | Each slot is announced with position |
Focus Management | Clear focus indicators and logical tab order |
ARIA Labels | Proper labeling for assistive technology |
High Contrast | Respects system color preferences |
Keyboard Navigation | Full keyboard control without mouse |
Error States | Screen readers announce validation errors |
Common patterns
Two-factor authentication - TOTP codes from authenticator apps or SMS verification.
Password reset - Email verification codes in your reset flow.
Payment verification - Extra security for transactions.
Account confirmation - Verify email addresses during signup.
Make OTP forms that work
- Auto-advance focus - Don't make users click each box
- Allow paste - Let them paste the whole code at once
- Mobile keyboards - Number pad for digits, full keyboard for mixed codes
- Clear errors - "Code expired" beats "Invalid code"
- Resend options - Always include "didn't get it?"
- Good instructions - Tell them where to find the code
Hover Card
A contextual popup that appears on hover, perfect for previewing content, user profiles, and additional information without leaving the current page.
Input
A flexible input component built with React and Tailwind CSS. Perfect for forms, search fields, and user data collection in Next.js applications using shadcn/ui components.