12 React Email Templates Every SaaS App Needs (2026)
If you're building a SaaS product with Next.js or React, you'll end up needing the same set of transactional emails that every SaaS eventually ships: welcome, verification, payment receipts, trial reminders, security alerts.
Writing and testing each one from scratch takes time — HTML email is notoriously tricky across clients, and Outlook alone can break a template in a dozen different ways.
This guide covers the 12 email templates every SaaS app needs, with React Email code examples, use cases, and subject line suggestions for each.
The 12 Templates
- Welcome Email
- Email Verification
- Magic Link / Passwordless Login
- OTP Verification
- Password Reset
- Payment Receipt
- Trial Started
- Trial Ending Soon
- Card Expiring
- Refund Processed
- Account Security Alert
- Invite a Team Member
1. Welcome Email
When to send
Immediately after a user signs up.
Why it matters
The welcome email is the first impression your product makes via email. It sets expectations, confirms the account is ready, and drives users back into the app to complete their first action.
What to include
- Brief confirmation that the account is active
- One clear CTA back to the dashboard or onboarding checklist
- Links to docs or support
Subject line ideas
Welcome to [Product] — let's get startedYour [Product] account is readyYou're in — here's where to start
import { Button, Container, Head, Heading, Html, Preview, Text } from '@react-email/components';
interface WelcomeEmailProps { username: string; dashboardUrl: string;}
export function WelcomeEmail({ username, dashboardUrl }: WelcomeEmailProps) { return ( <Html> <Head /> <Preview>Your account is ready — let's get started</Preview> <Container style={{ maxWidth: '560px', margin: '0 auto', padding: '40px 20px' }}> <Heading>Welcome, {username}!</Heading> <Text>Your account is set up. Click below to get started.</Text> <Button href={dashboardUrl} style={{ backgroundColor: '#000', color: '#fff', padding: '12px 24px', borderRadius: '6px' }}> Go to Dashboard </Button> </Container> </Html> );}
2. Email Verification
When to send
Right after signup, before the user can access core features.
Why it matters
Verifying email addresses reduces spam signups and ensures your users receive your emails. It's also required by many compliance frameworks.
What to include
- A prominent verification button
- A fallback plain-text URL
- Link expiry information
Subject line ideas
Verify your email for [Product]Confirm your email addressOne click to activate your account
import { Button, Container, Head, Html, Preview, Text } from '@react-email/components';
interface EmailVerificationProps { verificationUrl: string; expiresIn?: string;}
export function EmailVerification({ verificationUrl, expiresIn = '24 hours' }: EmailVerificationProps) { return ( <Html> <Head /> <Preview>Verify your email address</Preview> <Container style={{ maxWidth: '560px', margin: '0 auto', padding: '40px 20px' }}> <Text style={{ fontSize: '16px' }}>Click the button below to verify your email address.</Text> <Button href={verificationUrl} style={{ backgroundColor: '#000', color: '#fff', padding: '12px 24px', borderRadius: '6px' }}> Verify Email </Button> <Text style={{ fontSize: '14px', color: '#6b7280' }}> This link expires in {expiresIn}. If you didn't sign up, you can ignore this email. </Text> </Container> </Html> );}
3. Magic Link / Passwordless Login
When to send
When a user requests a passwordless login link.
Why it matters
Magic links are increasingly common for SaaS apps — they eliminate passwords and reduce friction. The email needs to be fast, clear, and expire quickly.
What to include
- A single prominent "Sign In" button
- Link expiry (usually 15–30 minutes)
- A note that the link is single-use
Subject line ideas
Your sign-in link for [Product]Click here to sign in — expires in 15 minutesMagic link to access [Product]
import { Button, Container, Head, Html, Preview, Text } from '@react-email/components';
interface MagicLinkEmailProps { magicLinkUrl: string; expiresIn?: string;}
export function MagicLinkEmail({ magicLinkUrl, expiresIn = '15 minutes' }: MagicLinkEmailProps) { return ( <Html> <Head /> <Preview>Your sign-in link — expires in {expiresIn}</Preview> <Container style={{ maxWidth: '560px', margin: '0 auto', padding: '40px 20px' }}> <Text style={{ fontSize: '16px' }}>Click the button below to sign in. This link expires in {expiresIn} and can only be used once.</Text> <Button href={magicLinkUrl} style={{ backgroundColor: '#000', color: '#fff', padding: '12px 24px', borderRadius: '6px' }}> Sign In </Button> <Text style={{ fontSize: '14px', color: '#6b7280' }}> If you didn't request this, you can safely ignore this email. </Text> </Container> </Html> );}
4. OTP Verification
When to send
When a user needs to verify their identity with a one-time code — 2FA, account recovery, suspicious login.
What to include
- The code displayed prominently
- Expiry time (usually 5–10 minutes)
- Clear instruction not to share the code
Subject line ideas
Your [Product] verification code: {code}{code} is your [Product] codeVerification code: {code}
import { Container, Head, Html, Preview, Section, Text } from '@react-email/components';
interface OTPEmailProps { code: string; expiresIn?: string;}
export function OTPEmail({ code, expiresIn = '10 minutes' }: OTPEmailProps) { return ( <Html> <Head /> <Preview>Your verification code: {code}</Preview> <Container style={{ maxWidth: '560px', margin: '0 auto', padding: '40px 20px' }}> <Text>Your one-time verification code:</Text> <Section style={{ background: '#f4f4f5', padding: '20px', borderRadius: '8px', textAlign: 'center' }}> <Text style={{ fontSize: '36px', fontWeight: 'bold', letterSpacing: '10px', margin: 0 }}> {code} </Text> </Section> <Text style={{ fontSize: '14px', color: '#6b7280' }}> Expires in {expiresIn}. Never share this code with anyone. </Text> </Container> </Html> );}
5. Password Reset
When to send
When a user requests a password reset.
What to include
- Clear instruction that this was requested
- A prominent reset button
- A note that the link expires
- Reassurance that if they didn't request it, nothing will happen
Subject line ideas
Reset your [Product] passwordPassword reset request for [Product]Your password reset link
6. Payment Receipt
When to send
Immediately after a successful payment or subscription renewal.
Why it matters
Payment receipts are often required for expense reimbursement. A clean, detailed receipt reduces support tickets.
What to include
- Invoice amount and date
- Invoice number
- Payment method (last 4 digits)
- Download link for the PDF invoice
- Support contact
Subject line ideas
Your [Product] receipt — $X.XXPayment confirmed: Invoice #[number]Receipt for your [Product] subscription
7. Trial Started
When to send
When a user activates a free trial.
What to include
- Trial duration and exact end date
- What they can do during the trial
- 2–3 key actions to take to get value quickly
- Link to upgrade
Subject line ideas
Your [Product] trial is now active — {X} days to exploreTrial started: you have full access until {date}{X} days to try everything in [Product]
8. Trial Ending Soon
When to send
3 days before trial ends, 1 day before, and (optionally) on the last day.
Why it matters
This is one of the highest-converting emails you'll send. Users who are on trial and haven't upgraded yet need a nudge — the trial reminder is it.
What to include
- Exactly how many days are left
- What happens when the trial ends (downgrade, data retention policy)
- A prominent upgrade CTA
- Optional: what they've accomplished during the trial
Subject line ideas
Your trial ends in {X} days — keep your access{X} days left on your [Product] trialDon't lose your [Product] workspace
9. Card Expiring
When to send
30 days before a card on file expires, and again at 7 days.
Why it matters
A failed payment means churn. Proactively reminding users to update their card prevents involuntary churn.
What to include
- Which card is expiring (last 4 digits)
- When it expires
- A direct link to update billing details
Subject line ideas
Action required: your card expires soonUpdate your payment method for [Product]Your card ending in {XXXX} expires {month}
10. Refund Processed
When to send
When a refund is issued, usually immediately after processing.
What to include
- Amount refunded
- Original payment date
- Expected time to appear on statement (typically 5–10 business days)
- Reference/transaction ID
- Support contact for questions
Subject line ideas
Your refund has been processed — $X.XXRefund confirmation: $X.XXWe've issued your refund
11. Account Security Alert
When to send
On suspicious activity: new device login, password change, 2FA disabled, email address change.
Why it matters
Security alerts build trust and give users a chance to lock down their account if something looks wrong.
What to include
- What happened (login from new device, etc.)
- When and where (timestamp, IP address, location if available)
- A direct link to secure the account
- Contact for support
Subject line ideas
New sign-in to your [Product] accountSecurity alert: someone signed in from a new deviceDid you just sign in from [City]?
12. Invite a Team Member
When to send
When a user sends a team invitation from within the app.
What to include
- Who invited them
- What [Product] is (in case the recipient doesn't know)
- A prominent "Accept Invitation" button
- Link expiry
Subject line ideas
{Name} invited you to join [Product]You've been invited to [workspace name] on [Product]Your invitation to [Product]
import { Button, Container, Head, Html, Preview, Text } from '@react-email/components';
interface InviteEmailProps { inviterName: string; workspaceName: string; inviteUrl: string; expiresIn?: string;}
export function InviteEmail({ inviterName, workspaceName, inviteUrl, expiresIn = '7 days' }: InviteEmailProps) { return ( <Html> <Head /> <Preview>{inviterName} invited you to join {workspaceName}</Preview> <Container style={{ maxWidth: '560px', margin: '0 auto', padding: '40px 20px' }}> <Text style={{ fontSize: '16px' }}> <strong>{inviterName}</strong> has invited you to join <strong>{workspaceName}</strong>. </Text> <Button href={inviteUrl} style={{ backgroundColor: '#000', color: '#fff', padding: '12px 24px', borderRadius: '6px' }}> Accept Invitation </Button> <Text style={{ fontSize: '14px', color: '#6b7280' }}> This invitation expires in {expiresIn}. </Text> </Container> </Html> );}
The Full Email Flow for a SaaS App
Here's how all 12 templates fit together across the user lifecycle:
| Stage | Emails | |-------|--------| | Signup | Welcome, Email Verification | | Authentication | Magic Link, OTP, Password Reset | | Trial | Trial Started, Trial Ending (×2–3), Trial Ending Last Day | | Billing | Payment Receipt, Card Expiring, Refund Processed | | Security | Account Security Alert | | Growth | Invite a Team Member |
Writing and Testing These Templates
Writing each template from scratch in React Email is straightforward, but testing them is where the time goes. You need to check rendering in:
- Gmail (web, iOS, Android)
- Outlook (2016, 2019, 2021, Mac)
- Apple Mail
- Yahoo Mail
- Mobile clients in light and dark mode
Common issues:
- Outlook ignores many CSS properties — use inline styles and table-based layouts from
@react-email/components - Dark mode inverts colors unpredictably — test with explicit background and text colors
- Font fallbacks — Google Fonts work in most clients but not Outlook; always specify a system font fallback
For setup guides, see:
- How to send React Email with Resend in Next.js
- Setting up React Email in a monorepo
- Best React email templates for SaaS onboarding
Skip the Boilerplate
If you don't want to design, write, and cross-client test all 12 templates from scratch, our React Email Templates bundle includes all of them — production-ready, TypeScript-typed, tested on Gmail, Outlook, Apple Mail, and mobile clients in both light and dark mode. Figma source files included. Buy once, use in unlimited projects.
