Six-digit OTP input with paste, backspace and arrow-key support.
Set your access key from API keys as NEXTUI_TOKEN in .env.local and add the @nextui namespace below to components.json once. Then every item installs by name. Each install counts as a copy on a free account.
$pnpm dlx shadcn@latest add @nextui/otp-input
1{2"registries": {3"@nextui": {4"url": "https://nextui.dev/r/{name}.json",5"headers": { "Authorization": "Bearer ${NEXTUI_TOKEN}" }6}7}8}
1"use client";23import { OneTimeCodeInput } from "@/components/nextui/otp-input";45export function VerifyPhone() {6return (7<OneTimeCodeInput8length={4}9separator={false}10label="Enter the code we texted you"11completeText="Checking your code…"12onComplete={(code) => fetch("/api/verify", { method: "POST", body: JSON.stringify({ code }) })}13onResend={() => fetch("/api/resend", { method: "POST" })}14/>15);16}
| Prop | Type | Default | Description |
|---|---|---|---|
| length | number | 6 | Number of digit boxes |
| label | ReactNode | "Enter the 6-digit code" | Label above the boxes; follows length by default |
| separator | boolean | true | Show a dash between the two halves |
| value | string | – | Controlled code |
| defaultValue | string | "" | Starting code when uncontrolled |
| onChange | (code: string) => void | – | Called whenever a digit changes |
| onComplete | (code: string) => void | – | Called once every box is filled |
| onResend | () => void | – | The Resend code link was clicked |
| completeText | ReactNode | "Verifying…" | Shown under the boxes once the code is complete |
| resendPrompt | ReactNode | "Didn’t get it? " | Text before the resend link |
| resendLabel | ReactNode | "Resend code" | Text of the resend link |
| className | string | – | Extra classes on the wrapper |
Sign in to see the code
Preview it freely. A free account copies code and prompts a few times a day.