All templates
authentication

Password Reset Template

Allow users to securely reset their password

Preview

import {
  Body,
  Button,
  Container,
  Head,
  Heading,
  Hr,
  Html,
  Link,
  Preview,
  Section,
  Text,
} from "@react-email/components";

type PasswordResetProps = {
  name: string;
  resetUrl: string;
  expiryTime: string;
};

export function PasswordResetEmail({ name, resetUrl, expiryTime }: PasswordResetProps) {
  return (
    <Html>
      <Head />
      <Preview>Reset your password</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>Reset your password</Heading>
          <Text style={text}>Hi {name},</Text>
          <Text style={text}>
            We received a request to reset your password. Click the button below
            to choose a new one:
          </Text>
          <Section style={buttonContainer}>
            <Button style={button} href={resetUrl}>
              Reset Password
            </Button>
          </Section>
          <Text style={muted}>
            This link will expire in {expiryTime}. If you didn't request a
            password reset, you can safely ignore this email.
          </Text>
          <Hr style={hr} />
          <Text style={footer}>
            If the button doesn't work, copy and paste this link:
            <br />
            <Link href={resetUrl} style={link}>{resetUrl}</Link>
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

const main = {
  backgroundColor: "#f6f9fc",
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
};

const container = {
  backgroundColor: "#ffffff",
  margin: "0 auto",
  padding: "40px 20px",
  maxWidth: "480px",
};

const h1 = {
  color: "#1f2937",
  fontSize: "24px",
  fontWeight: "600",
  margin: "0 0 20px",
};

const text = {
  color: "#374151",
  fontSize: "16px",
  lineHeight: "24px",
  margin: "0 0 16px",
};

const muted = {
  color: "#6b7280",
  fontSize: "14px",
  lineHeight: "20px",
};

const buttonContainer = {
  textAlign: "center" as const,
  margin: "32px 0",
};

const button = {
  backgroundColor: "#dc2626",
  borderRadius: "8px",
  color: "#fff",
  fontSize: "16px",
  fontWeight: "600",
  padding: "12px 24px",
  textDecoration: "none",
};

const hr = {
  borderColor: "#e5e7eb",
  margin: "24px 0",
};

const footer = {
  color: "#9ca3af",
  fontSize: "12px",
  lineHeight: "18px",
};

const link = {
  color: "#4f46e5",
  wordBreak: "break-all" as const,
};

Install: npm install @react-email/components

Template Variables

Pass these props to your email component:

VariableDescription
nameUser's first name
resetUrlUnique password reset link
expiryTimeLink expiration time (e.g., '1 hour')

Best Practices

Security

  • Set expiration to 15-60 minutes (shorter is safer)
  • Use cryptographically random tokens (at least 32 bytes)
  • Invalidate token after single use
  • Don't reveal whether the email exists in your system

User Experience

  • Include the plain URL as fallback text
  • Clearly state when the link expires
  • Make it easy to request a new link if expired

Monitoring

  • Log reset attempts for fraud detection
  • Rate limit requests per email (e.g., 3 per hour)
  • Alert users of password changes via separate email

Ready to send emails?

Get started with 1,000 free emails per month.

Start for free