Email entry that sends a one-time password reset link.
Enter your email and we'll send you a reset link.
Install with the CLI, or add the packages and paste the source below.
Add Forgot Password to your app with its source-owned dependencies.
npx cronus-ui add forgot-password
Install the Cronus UI packages, then paste the block below.
Copy the source for Request link. Every class is a semantic token, so it re-themes with your app.
"use client";import {Button,Card,CardContent,CardFooter,CardHeader,CardTitle,Input,Label,} from "@cronus-ui/ui";import { requestPasswordReset } from "../lib/auth-adapter.js";import { ArrowLeft, KeyRound, MailCheck } from "lucide-react";import { type FormEvent, useState } from "react";export function ForgotPasswordBlock() {const [pending, setPending] = useState(false);const [error, setError] = useState<string | null>(null);const [sentTo, setSentTo] = useState<string | null>(null);async function sendTo(email: string) {setError(null);setPending(true);try {await requestPasswordReset({ email });setSentTo(email);} catch (err) {setError(err instanceof Error ? err.message : "Something went wrong.");} finally {setPending(false);}}async function onSubmit(event: FormEvent<HTMLFormElement>) {event.preventDefault();const form = new FormData(event.currentTarget);await sendTo(String(form.get("email") ?? ""));}if (sentTo) {return (<div className="flex w-full items-center justify-center py-4"><Card className="w-full max-w-sm gap-6 shadow-lg"><CardHeader className="flex flex-col items-center gap-3 text-center"><span className="inline-flex size-11 items-center justify-center rounded-xl bg-success/10 text-success"><MailCheck className="size-5" aria-hidden="true" /></span><div className="flex flex-col gap-1"><CardTitle className="font-display text-xl">Check your inbox</CardTitle><p className="text-sm text-fg-secondary">We sent a password reset link to{" "}<span className="font-medium text-fg">{sentTo}</span>.</p></div></CardHeader><CardContent className="flex flex-col gap-4">{error ? (<p role="alert" className="text-sm text-error-strong">{error}</p>) : (<p className="text-center text-sm text-fg-secondary">Didn't get it? Check your spam folder, or resend below.</p>)}<Buttontype="button"variant="primary"size="lg"className="w-full"disabled={pending}aria-busy={pending}onClick={() => void sendTo(sentTo)}>{pending ? "Sending…" : "Resend email"}</Button><Button type="button" variant="ghost" className="w-full" onClick={() => setSentTo(null)}>Use a different email</Button></CardContent><CardFooter className="justify-center"><ahref="/login"className="inline-flex items-center justify-center gap-1.5 text-sm font-medium text-fg-secondary transition-colors hover:text-fg"><ArrowLeft className="size-4" aria-hidden="true" />Back to sign in</a></CardFooter></Card></div>);}return (<div className="flex w-full items-center justify-center py-4"><Card className="w-full max-w-sm gap-6 shadow-lg"><CardHeader className="flex flex-col items-center gap-3 text-center"><span className="inline-flex size-11 items-center justify-center rounded-xl bg-gradient-primary text-primary-foreground shadow-glow"><KeyRound className="size-5" aria-hidden="true" /></span><div className="flex flex-col gap-1"><CardTitle className="font-display text-xl">Reset your password</CardTitle><p className="text-sm text-fg-secondary">Enter your email and we'll send you a reset link.</p></div></CardHeader><CardContent><form onSubmit={onSubmit} className="flex flex-col gap-4" aria-busy={pending}><div className="flex flex-col gap-2"><Label htmlFor="forgot-email">Email</Label><Inputid="forgot-email"name="email"type="email"placeholder="you@company.com"autoComplete="email"/></div>{error ? (<p role="alert" className="text-sm text-error-strong">{error}</p>) : null}<Buttontype="submit"variant="primary"size="lg"className="w-full"disabled={pending}aria-busy={pending}>{pending ? "Sending…" : "Send reset link"}</Button></form></CardContent><CardFooter className="justify-center"><ahref="/login"className="inline-flex items-center justify-center gap-1.5 text-sm font-medium text-fg-secondary transition-colors hover:text-fg"><ArrowLeft className="size-4" aria-hidden="true" />Back to sign in</a></CardFooter></Card></div>);}
Enter your email and we'll send you a reset link.