Email System
Transactional emails with Resend for authentication and notifications.
Email Types
- • Magic link authentication
- • Welcome emails
- • Subscription confirmations
- • Payment notifications
- • Waitlist updates
Features
- • Branded templates
- • Dynamic content
- • Delivery tracking
- • Domain verification
Setup
- 1. Create account at resend.com
- 2. Create an API key
- 3. Verify your domain (recommended)
.env
AUTH_RESEND_KEY="re_..."EMAIL_FROM="noreply@yourdomain.com"
Verify your domain to improve deliverability and remove the "via resend.dev" label.
Email Service
src/server/lib/emailService.ts
1import { Resend } from "resend";23const resend = new Resend(process.env.AUTH_RESEND_KEY);45export async function sendEmail({ to, subject, html }) {6 const { data, error } = await resend.emails.send({7 from: `Your SaaS <${process.env.EMAIL_FROM}>`,8 to: [to],9 subject,10 html,11 });1213 if (error) throw new Error(error.message);14 return data;15}1617// Send welcome email18export async function sendWelcomeEmail(email: string, name?: string) {19 return sendEmail({20 to: email,21 subject: "Welcome!",22 html: generateWelcomeEmailHTML(name),23 });24}
Auth Integration
Magic link emails are handled by NextAuth.js with Resend:
1// auth.config.ts2import Resend from "next-auth/providers/resend";34export default {5 providers: [6 Resend({7 apiKey: process.env.AUTH_RESEND_KEY,8 from: process.env.EMAIL_FROM,9 }),10 ],11};
Webhook Triggers
Send emails on Stripe events:
1switch (event.type) {2 case "customer.subscription.created":3 const subscription = event.data.object;4 const customer = await stripe.customers.retrieve(subscription.customer);56 if (customer.email) {7 await sendSubscriptionConfirmation(customer.email, "Pro", "$20/month");8 }9 break;10}
Best Practices
Deliverability
- • Verify your domain
- • Use clear subject lines
- • Include unsubscribe links
- • Monitor bounce rates
UX
- • Keep emails mobile-friendly
- • Consistent branding
- • Clear calls-to-action
- • Handle errors gracefully
Troubleshooting
Emails not sending
Check AUTH_RESEND_KEY and EMAIL_FROM. Verify domain in Resend dashboard.
Going to spam
Set up domain verification and DKIM records. Avoid spammy content.
Magic links not working
Ensure NEXTAUTH_URL matches your domain and EMAIL_FROM is verified.
Next: Theming
Color system and customization