UI components · Form input
OTP Input
Also called: Verification code input, PIN input, One-time code field, InputOTP
A row of small boxes for a text or email verification code, one digit per box. Typing a digit jumps to the next box. Common in sign-in, sign-up, and extra checks before sensitive actions.
Click “Labeled” to see what each part is called, or “Anti-pattern” to see the most common mistake.
How to tell AI
Swap in your own content firstBuild a text-message verification page. Title: "Enter verification code." Below it, a gray line "We sent a 6-digit code to (206) •••-0142" and a "Change number" link. In the middle, 6 boxes of 48×56px with 8px gaps and 24px centered digits; the current box has a darker border and a blinking cursor. Typing a digit moves to the next box, Backspace moves back, and pasting 6 digits fills all boxes at once. On phones, show the number pad, and add `autocomplete="one-time-code"` to support autofill. When all boxes are filled, verify automatically and show loading. If the code is wrong, turn all 6 boxes red, show "That code isn't right. Try again." below, and clear them. Under the boxes, show a "Resend in 59s" countdown that turns into a clickable "Resend code" when it ends.
Send to
01Decide
Does your content look like this?
Check both columns to confirm OTP Input is what you need.
Use OTP Input when
- Entering the code from a text or email when signing in or signing up with a phone number or email
- An extra check before sensitive actions like changing a password, adding a bank card, or making a large payment
- Two-factor authentication, entering the 6-digit code from an authenticator app
Pick something else when
Passwords or invite codes with variable length and letters. Use a regular input.
Use insteadInputCAPTCHAs or slider checks to stop bots. That's a different kind of component.
Long strings over 8 characters (like license keys). Boxes make them harder to type. Use a regular input with grouped formatting.
Use insteadInput
Not sure? Upload a screenshot and page analysis will check which layout each block should use.
02Pitfalls
Common misuse
It looks like it works, but it makes things harder for users.
- 01
Each box is a separate input with no paste support, so the 6-digit code copied from a text lands entirely in the first box
The wireframe below shows this case. The red dashed box marks the problem.The wireframe on the right shows this case. The red dashed box marks the problem.
- 02
No resend countdown or resend button, so users who never got the text can only reload the page
- 03
On a wrong code the boxes just shake, without saying whether it's wrong or expired, and nothing gets cleared
03Spot it
How to spot it
Look at the overall structure first, then check a few features you can spot at a glance.
Structure
A line saying where the code was sent (phone number or email), a row of 4 to 6 single-character boxes, a resend countdown, and a submit button. Errors show below the boxes.
PartsClick one to highlight it in the wireframe above
04Explained
In detail
An OTP input splits a 4- to 6-digit one-time code into a row of equal boxes, one digit each. After each digit, the cursor jumps to the next box, and Backspace goes back one. If users copy the whole code from a text message and paste it, it should fill every box at once. On phones, it should bring up the number pad and support the system's code autofill (autocomplete="one-time-code"). It usually comes with a line like "Code sent to (206) •••-0142" and a "Resend in 59s" countdown.
It only differs from a regular Input in looks and behavior. Under the hood you're still typing a string of digits, so many solid implementations use one hidden input plus a row of boxes that only display the digits. That way paste, autofill, and screen readers all just work. It's also not a CAPTCHA (typing letters from an image or dragging a slider to prove you're human). That's a different thing.
Match the number of boxes to the real code length, and make them big enough (at least 40px wide on phones). You can auto-submit when the last digit is filled, but show a loading state and block double submits. On a wrong code, turn the whole row red, say whether it's wrong or expired, and clear it so they can retry. Keep "Resend" disabled until the countdown ends, and give people a backup if the text never arrives (a voice call, or email instead).
Developer infoTerm ID, DOM cues, match priority
- Term ID
component-otp-input- DOM selectors
The extension matches these CSS selectors when it inspects a page locally (tags, ARIA roles, common component library classes).
input[autocomplete="one-time-code"].ant-otp[data-input-otp-container][data-input-otp][data-slot="input-otp"][data-slot="input-otp-group"].n-input-otp.arco-verification-code.van-password-input.chakra-pin-input.mantine-PinInput-root[class*="MuiOtpInput-Box"]
- Class keywords
Class names, ids and data-testid are split into words and matched in order, so page-header, PageHeader_root__x7a and pageHeader all become page, header.
otp-inputotp-inputsotpotp-fieldverification-codeverify-codecode-inputcode-inputspin-inputsms-code
- Component names
React / Vue component names read in development mode. Case-insensitive; library prefixes such as El, Ant and Mui are dropped.
InputOTPOTPInputOtpInputPinInputVerificationCodeCodeInputPinField
- Structure
Computed from how the element is laid out and styled. It only adds to the score and never decides on its own.
form controlsrepeated items
- Priority
- 3 · when several match at the same level, the higher priority wins
- Version
- v2 · updated Sep 30, 2026