Password reset emails done right
Security-first design, clear expiry messaging, and a single CTA that drives reset completion. Production-ready for React Email.
Anatomy of a secure reset email
Six elements that drive reset completion and build trust
Brand header
Your logo and product name. Tells the user the email is legitimate before they read a word.
Clear expiry time
"This link expires in 60 minutes." Visible, specific, and near the top of the email.
Single primary CTA
One large button: "Reset your password." No competing links, no distractions.
Fallback text link
A plain-text URL below the button for email clients that block buttons.
Security disclaimer
"If you didn't request this, you can safely ignore this email." Builds trust.
Support contact
A direct link to your support team. Reduces anxiety and prevents abandoned resets.
Common mistakes to avoid
These errors cause failed resets, support tickets, and security concerns
No expiry shown
Users don't know how long the link is valid. They bookmark it and come back hours later.
Multiple CTAs
Competing buttons confuse users. They click the wrong one or abandon the flow entirely.
Generic sender
"noreply@mail.com" looks like phishing. Use your brand name and domain.
No fallback link
Button-blocking email clients leave users stuck. Always include a plain-text URL.
Missing disclaimer
Without "ignore if you didn't request this," users worry their account is compromised.
Tiny tap targets
Small buttons on mobile cause mis-taps and frustration. 44px minimum height.
Security checklist
Every security consideration built into the template
Token security
- Cryptographically random, single-use tokens
- Configurable expiry (15-60 minutes)
- Token invalidated after successful reset
- HTTPS-only reset links enforced
- Rate limiting on reset requests
Email security
- Clear "ignore if not you" disclaimer
- No sensitive data in the email body
- Branded sender with SPF/DKIM/DMARC
- Plain-text fallback link included
- Support contact for suspicious activity
Quick integration
Send password reset emails with Resend in under 10 lines
Resend integration
import { Resend } from 'resend'
import { PasswordResetEmail } from '@/emails/password-reset'
const resend = new Resend(process.env.RESEND_API_KEY)
await resend.emails.send({
from: 'YourApp <security@yourapp.com>',
to: user.email,
subject: 'Reset your password',
react: PasswordResetEmail({
resetLink,
userEmail: user.email,
expiryMinutes: 60,
})
})Subject line matters. Use clear, branded subject lines like “Reset your [AppName] password”. Avoid urgency words that trigger spam filters. Always include your product name for recognition.
Template features
Password resets that actually reach the inbox
Security-first design
Expiry warnings, security disclaimers, and single-use token messaging built in.
Mobile optimized
Large tap targets, readable fonts, and responsive layout on every device.
TypeScript props
Typed interface for reset URL, expiry, branding, and support contact.
Dark mode ready
Adapts to light and dark mode in Gmail, Outlook, and Apple Mail.
Quick integration
Drop-in examples for Resend, Postmark, SendGrid, and AWS SES.
Cross-client tested
Verified in Gmail, Outlook, Apple Mail, Yahoo, and Samsung Mail.
Frequently asked questions
How long should a password reset link be valid?
30-60 minutes for most apps. Shorter (15 min) for high-security applications like banking. Always show the expiry time clearly in the email.
Should password reset emails include the username?
Yes, but only the email address or a masked version. Never include the current or previous password. Showing the email helps users confirm the reset is for the right account.
How do I prevent password reset emails from going to spam?
Use proper SPF, DKIM, and DMARC records. Send from your own domain (not a third-party). Keep subject lines clear and avoid spam trigger words like "urgent" or "act now."
Can I customize the branding?
All props are optional. Modify logo, colors, copy, and support links through TypeScript props while maintaining the cross-client-tested layout.
Never build a reset flow from scratch again
Includes this password reset template plus 60+ others for verification, magic links, billing, and onboarding. Pay once, get every future update.