shadcn.io is an independent project built on shadcn/ui
A mail icon sits above Check your email and user@example.com. Six boxes follow, then Verify Email and a Resend code button.
Use this after you email a code. If the message can carry a link, a Button on that page can confirm without typing. In React, Base UI does not verify the code.
Installation
Anatomy

Usage
<div className="flex w-full max-w-sm flex-col gap-6">
<div className="flex flex-col items-center gap-2 text-center">
<div className="flex size-12 items-center justify-center rounded-full bg-primary/10">
<MailIcon aria-hidden="true" className="size-6 text-primary" />
</div>
<h2 className="font-semibold text-2xl">Check your email</h2>
<p className="text-muted-foreground text-sm">
We sent a verification code to{" "}
<span className="font-medium">user@example.com</span>
</p>
</div>
<form className="flex flex-col gap-6" onSubmit={handleSubmit}>
<Field invalid={error !== ""}>
<FieldLabel className="sr-only" htmlFor="email-code">
Verification code
</FieldLabel>
<div className="flex justify-center">
<InputOTP
id="email-code"
maxLength={6}
onChange={handleValueChange}
value={value}
>
<InputOTPGroup>
<InputOTPSlot className="bg-background" index={0} />
<InputOTPSlot className="bg-background" index={1} />
<InputOTPSlot className="bg-background" index={2} />
</InputOTPGroup>
<InputOTPSeparator />
<InputOTPGroup>
<InputOTPSlot className="bg-background" index={3} />
{/* The rest of the file is under Installation. */}FAQ
How is the header built?
A MailIcon in a size-12 circle with bg-primary/10, a heading, and a line naming the address in font-medium. The icon has aria-hidden.
What happens when Verify Email is pressed early?
A code shorter than six shows Verification code must be 6 characters. in FieldError, centered under the field.
How does the button show progress?
While verifying, the button is disabled and reads Verifying...; a timer stands in for the request. The example shows the result in a status line under the form instead of calling an API. Replace that with your request, and show its error in FieldError when the code is rejected.
What does Resend code do?
It clears the field and any error and says a new code is on its way. Call your API there, and add a countdown as the SMS Verification example does.
API Reference
Field
Sets invalid={error !== ""} and htmlFor="email-code". The rest is on the Field page.
Input OTP
Sets id="email-code", maxLength={6}, onChange={handleValueChange}, value={value}, index={0} and index={1}. The rest is on the Input OTP page.
Button
Sets disabled={isVerifying}, type="submit", onClick={handleResend}, type="button" and variant="link". The rest is on the Button page.





