Email Integration
Our boilerplate uses Resend by default, but you can integrate any email service provider. Email functionality is essential for features like authentication, notifications, and user engagement.
Getting Started with Resend
- Sign up for a Resend account at resend.com
- Navigate to the Domains section and select "New Domain". We suggest using a dedicated subdomain (e.g., mail.yourapp.com) for better email deliverability.
- Follow the domain verification process by adding the required DNS records. Verification typically completes within 5-10 minutes after DNS propagation.
- In the API Keys section, generate a new key. Give it a descriptive name like "Production API Key" or "Development Key".
- Store your API key in the environment file as RESEND_API_KEY
- Keep your API key secure - it won't be shown again after generation
Email Delivery Methods
The boilerplate supports two email delivery methods:
1. Built-in SMTP
Used automatically for system emails like authentication links and security notifications.
2. Direct API Integration
For custom emails and transactional messages, use our streamlined sendEmail utility:
import { sendEmail } from "@/lib/resend";// Example: Onboarding sequence emailawait sendEmail({to: user.email,subject: "Getting Started with Your App",template: "onboarding",data: {username: user.username,nextSteps: ["Complete profile", "Add team members"],},});
Email Response Handling
While Resend currently doesn't handle incoming emails, we've implemented a solution for managing responses.
Configure your support email address in the config file to handle replies:
// config/email.tsexport const emailConfig = {support: {email: "help@yourapp.com",name: "YourApp Support"}};// Sending with reply-to configurationawait sendEmail({to: customer.email,subject: "Your Account Update",template: "account-change",replyTo: emailConfig.support,data: {changes: ["Plan upgrade", "New features unlocked"],effectiveDate: "2024-03-20"}});
Implementation Details
The sendEmail utility is located at src/lib/email/resend.ts
. Here's the complete implementation:
import { Resend } from 'resend';// Initialize Resend clientconst resendApiKey = process.env.RESEND_API_KEY;export const resend = new Resend(resendApiKey);// Email payload typeexport type EmailPayload = {to: string | string[];subject: string;html?: string;text?: string;from?: string;replyTo?: string;cc?: string | string[];bcc?: string | string[];attachments?: {filename: string;content: Buffer;}[];};// Default sender emailexport const defaultFrom = process.env.EMAIL_FROM || 'no-reply@yourdomain.com';// Send an email using Resendexport async function sendEmail(payload: EmailPayload) {const {to,subject,html,text,from = defaultFrom,replyTo,cc,bcc,attachments} = payload;try {const result = await resend.emails.send({from,to,subject,html,text,replyTo,cc,bcc,attachments,});console.log("Email sent successfully:", result);return { success: true, data: result };} catch (error) {console.error('Failed to send email:', error);return { success: false, error };}}
The function handles all common email scenarios including:
- Multiple recipients (to, cc, bcc)
- HTML and plain text content
- File attachments
- Custom reply-to addresses
- Error handling and logging