Email functionality powered by React Email and Resend. Build beautiful, responsive email templates using React components and send them through Resend’s reliable delivery infrastructure.
Key features
- React components for email templates
- TailwindCSS styling support
- Development mode (logs emails to console, no API key needed)
- Pre-built templates for authentication and access management
For local development, emails are logged to the dev server console. No configuration needed.
For production and preview environments:
-
Create a Resend account - sign up at resend.com
-
Verify your domain - add and verify your domain in the Resend dashboard
-
Generate an API key - create an API key in the Resend dashboard
-
Add the secret - add
RESEND_API_KEYas a secret in Cloudflare for preview and production environments:Terminal window bunx wrangler secret put RESEND_API_KEY --env=previewTerminal window bunx wrangler secret put RESEND_API_KEY --env=production -
Configure the sender address - set
email.frominpackages/config/index.ts:email: {from: "Your App <hello@yourdomain.com>",}
| Function | Module | Purpose |
|---|---|---|
sendEmail({ to, subject, react, from? }) | @/email | Low-level email sending |
sendAuthOtpEmail({ to, otp }) | @/email/templates.server | Send OTP verification code |
sendAccessGrantedEmail({ to, productName }) | @/email/templates.server | Notify user of granted access |
sendAccessRevokedEmail({ to, productName }) | @/email/templates.server | Notify user of revoked access |
sendAccessFailureEmail({ to }) | @/email/templates.server | Notify user of access failure |
Sending Emails
Section titled “Sending Emails”Use the pre-built template functions for common scenarios:
import { sendAuthOtpEmail } from "@/email/templates.server"
await sendAuthOtpEmail({ to: "user@example.com", otp: "123456",})For custom emails, use the low-level sendEmail function:
import { sendEmail } from "@/email"import MyCustomEmail from "./templates/my-custom-email"
await sendEmail({ to: "user@example.com", subject: "Welcome!", react: <MyCustomEmail name="John" />,})The from address defaults to config.email.from. Pass from only when you need a different sender.
Creating Templates
Section titled “Creating Templates”Email templates are React components located in apps/email/templates/. They use React Email components for cross-client compatibility.
Preview templates in the browser:
bun dev:emailThis starts the React Email development server where you can browse and preview all templates with hot reloading.
Basic template structure:
import { Heading, Text } from "@react-email/components"import Layout from "./layout"
interface WelcomeEmailProps { name: string}
export default function WelcomeEmail({ name }: WelcomeEmailProps) { return ( <Layout> <Heading as="h1">Welcome, {name}!</Heading> <Text>Thanks for signing up.</Text> </Layout> )}The Layout component provides consistent styling with:
- TailwindCSS support
- Custom fonts (Inter)
- Footer with project name and website link
Built-in Templates
Section titled “Built-in Templates”| Template | File | Purpose |
|---|---|---|
AuthOtpEmail | auth-otp.tsx | OTP verification code |
AccessGrantedEmail | access.granted.tsx | Purchase confirmation |
AccessRevokedEmail | access.revoked.tsx | Access revocation notice |
AccessFailureEmail | access.failure.tsx | Access failure notification |
Development Mode
Section titled “Development Mode”When RESEND_API_KEY is not set (local development), emails are:
- Logged to the console with full content
- Stored in memory for testing
- Accessible via
GET /emails/sentendpoint (development only)
In production, sendEmail throws if RESEND_API_KEY is missing.
This allows you to develop and test email flows without sending real emails.