All templates
authentication

Magic Link Login Template

Passwordless authentication via email link

Preview

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

type MagicLinkProps = {
  loginUrl: string;
  expiryTime: string;
  companyName: string;
};

export function MagicLinkEmail({ loginUrl, expiryTime, companyName }: MagicLinkProps) {
  return (
    <Html>
      <Head />
      <Preview>Your login link for {companyName}</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>Sign in to {companyName}</Heading>
          <Text style={text}>
            Click the button below to sign in. No password required!
          </Text>
          <Section style={buttonContainer}>
            <Button style={button} href={loginUrl}>
              Sign In
            </Button>
          </Section>
          <Text style={muted}>
            This link expires in {expiryTime} and can only be used once.
          </Text>
          <Hr style={hr} />
          <Text style={footer}>
            If you didn't request this link, you can safely ignore this email.
          </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: "#8b5cf6",
  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",
};

Install: npm install @react-email/components

Template Variables

Pass these props to your email component:

VariableDescription
loginUrlUnique one-time login link
expiryTimeLink expiration time (e.g., '15 minutes')
companyNameYour company or product name

Best Practices

Security

  • Set short expiration (10-15 minutes)
  • Invalidate token after single use
  • Bind token to the requesting device/browser when possible
  • Rate limit requests (e.g., 5 per hour per email)

User Experience

  • Open the app in the same browser session
  • Show clear feedback if link is expired or used
  • Provide fallback to password login

When to Use

  • Great for low-frequency apps (users forget passwords)
  • Ideal for mobile where password entry is painful
  • Consider WebAuthn/passkeys as a modern alternative

Ready to send emails?

Get started with 1,000 free emails per month.

Start for free