Verify Email
better-auth-ui/verify-emailFreeComponent
A page prompting the user to verify their email, with a button to open their email provider and a resend button rate-limited by a cooldown timer.
Live preview
live · rendered by the registry
Rendered by better-auth-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://better-auth-ui.com/r/verify-email.jsonSource
1"use client"23import { useAuth, useSendVerificationEmail } from "@better-auth-ui/react"4import { useEffect, useState } from "react"5import { toast } from "sonner"67import { Button } from "@/components/ui/button"8import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"9import { FieldDescription } from "@/components/ui/field"10import { Spinner } from "@/components/ui/spinner"11import { cn } from "@/lib/utils"12import { OpenEmailButton } from "./open-email-button"13import { useIsHydrated } from "./use-is-hydrated"1415export type VerifyEmailProps = {16 className?: string17}1819/** Seconds the resend button stays disabled to prevent spamming the endpoint. */20const RESEND_COOLDOWN_SECONDS = 602122/**23 * Render a card prompting the user to verify their email, with a resend button24 * that is rate-limited by a cooldown timer.25 *26 * The target email is read from `sessionStorage` (set when sign-up or sign-in27 * redirects here); the OpenEmail/Resend controls are only shown when an email28 * is stored. The resend button is disabled while a cooldown is active and shows29 * the remaining seconds.30 *31 * @param className - Additional CSS classes applied to the card32 * @returns The verify-email card React element33 */34export function VerifyEmail({ className }: VerifyEmailProps) {35 const {36 authClient,37 basePaths,38 baseURL,39 localization,40 redirectTo,41 viewPaths,42 Link43 } = useAuth()4445 const isHydrated = useIsHydrated()46 const [email, setEmail] = useState(47 (isHydrated && sessionStorage.getItem("better-auth-ui.verify-email")) || ""48 )49 const [cooldown, setCooldown] = useState(RESEND_COOLDOWN_SECONDS)5051 useEffect(() => {52 setEmail(sessionStorage.getItem("better-auth-ui.verify-email") ?? "")53 }, [])5455 useEffect(() => {56 if (cooldown <= 0 || !email) return5758 const interval = setInterval(() => {59 setCooldown((current) => (current > 0 ? current - 1 : 0))60 }, 1000)6162 return () => clearInterval(interval)63 }, [cooldown, email])6465 const { mutate: sendVerificationEmail, isPending } = useSendVerificationEmail(66 authClient,67 {68 onSuccess: () => {69 toast.success(localization.auth.verificationEmailSent)70 setCooldown(RESEND_COOLDOWN_SECONDS)71 }72 }73 )7475 const isCoolingDown = cooldown > 07677 return (78 <Card className={cn("w-full max-w-sm", className)}>79 <CardHeader>80 <CardTitle className="text-xl font-semibold">81 {localization.auth.verifyEmail}82 </CardTitle>83// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from better-auth-ui
All 49 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Account Settingsaccount-settings | better-auth-ui | Components | Free | 2 deps | |
| Active Sessionsactive-sessions | better-auth-ui | Components | Free | 5 deps · 2 files | |
| Additional Fieldadditional-field | better-auth-ui | Components | Free | 5 deps | |
| Adminadmin | better-auth-ui | Components | Free | 4 deps · 3 files | |
| Anonymousanonymous | better-auth-ui | Components | Free | 4 deps · 3 files | |
| API Keyapi-key | better-auth-ui | Components | Free | 4 deps · 10 files | |
| Authauth | better-auth-ui | Components | Free | 2 deps | |
| Auth Providerauth-provider | better-auth-ui | Components | Free | 4 deps · 2 files |
