Email System Setup & Testing
LaunchKit includes a comprehensive email system built with Resend and React Email, providing beautiful transactional emails for your SaaS. This guide covers setup, customization, and testing.
Overview
Section titled “Overview”The email system includes:
- 7 Pre-built email templates for common SaaS scenarios
- React Email components for easy customization
- Test API endpoint for development and debugging
- Automatic email triggers from Stripe webhooks and user actions
Resend Setup
Section titled “Resend Setup”1. Create Resend Account
Section titled “1. Create Resend Account”- Go to Resend.com
- Sign up for an account
- Complete email verification
2. Domain Configuration
Section titled “2. Domain Configuration”For production use:
-
Go to Domains in Resend dashboard
-
Add your domain (e.g.,
yourapp.com
) -
Add DNS records as instructed:
- MX Record:
feedback-mx.resend.co
- TXT Record:
"v=spf1 include:_spf.resend.co ~all"
- CNAME Record:
resend._domainkey.yourapp.com
- MX Record:
-
Wait for DNS propagation and verification
For development/testing:
Use Resend’s shared domain:
- From email:
[email protected]
- No DNS setup required
- Good for testing, not recommended for production
3. Generate API Key
Section titled “3. Generate API Key”- Go to API Keys in Resend dashboard
- Click “Create API Key”
- Name it (e.g., “LaunchKit Production”)
- Copy the key:
re_...
4. Environment Configuration
Section titled “4. Environment Configuration”Add to your .env.local
:
# Resend Configuration
RESEND_API_KEY=re_your_api_key_here
Email Templates Overview
Section titled “Email Templates Overview”LaunchKit includes 7 professionally designed email templates:
Template Types
Section titled “Template Types”Purchase Confirmation (purchase-confirmation.tsx
)
- Sent after successful payment
- Includes order details, download links, GitHub access
- Contains invoice link and next steps
Payment Failed (payment-failed.tsx
)
- Sent when payment is declined
- Includes retry instructions and support contact
- Clear call-to-action to update payment method
Invoice Paid (invoice-paid.tsx
)
- Sent for successful recurring payments
- Contains invoice details and receipt
- Confirms continued service access
New Signup (new-signup.tsx
)
- Welcome email for new users
- Includes temporary password (if applicable)
- Dashboard access and getting started guide
GitHub Access Granted (github-access-granted.tsx
)
- Sent when repository access is granted
- Contains repository URL and clone instructions
- Includes documentation links
Checkout Expired (checkout-expired.tsx
)
- Abandoned cart recovery email
- Reminds users to complete purchase
- Includes product details and checkout link
Subscription Cancelled (subscription-cancelled.tsx
)
- Confirmation of cancellation
- Feedback request and reactivation offer
- Maintains positive relationship
Customizing Email Templates
Section titled “Customizing Email Templates”1. Template Location
Section titled “1. Template Location”All email templates are in /components/emails/
:
components/emails/
├── basic-template.tsx # Base template
├── checkout-expired.tsx
├── github-access-granted.tsx
├── invoice-paid.tsx
├── new-signup.tsx
├── payment-failed.tsx
├── purchase-confirmation.tsx
├── subscription-cancelled.tsx
2. Template Structure
Section titled “2. Template Structure”Each template is a React component using @react-email/components
:
import * as React from 'react';
import {
Body, Container, Head, Heading, Html, Img, Link,
Preview, Section, Text, Tailwind, Button, Hr
} from '@react-email/components';
interface EmailProps {
customerName?: string;
customerEmail?: string;
productName?: string;
// ... other props
}
const EmailTemplate = (props: EmailProps) => {
const {
customerName = 'Customer',
productName = 'Product',
// ... default values
} = props;
return (
<Html>
<Head />
<Preview>Your purchase confirmation for {productName}</Preview>
<Tailwind>
<Body className="bg-white font-sans">
<Container className="max-w-2xl mx-auto py-8">
{/* Email content */}
</Container>
</Body>
</Tailwind>
</Html>
);
};
export default EmailTemplate;
3. Customization Examples
Section titled “3. Customization Examples”Branding:
// Add your logo
<Img
src="https://yourdomain.com/logo.png"
width="120"
height="40"
alt="Your App Logo"
className="mb-6"
/>
// Update colors
<Button
className="bg-blue-600 text-white px-6 py-3 rounded-lg"
href={dashboardUrl}
>
Access Dashboard
</Button>
Content:
// Customize messaging
<Heading className="text-2xl font-bold text-gray-900 mb-4">
Welcome to {appName}! 🎉
</Heading>
<Text className="text-gray-600 mb-6">
Thanks for joining thousands of developers who trust {appName}
to launch their SaaS applications faster.
</Text>
Testing Email System
Section titled “Testing Email System”1. Test API Endpoint
Section titled “1. Test API Endpoint”LaunchKit includes a powerful testing endpoint at /api/test-email
for debugging and previewing emails.
Basic Testing
Section titled “Basic Testing”# Send all 7 email types to default address
GET http://localhost:3000/api/test-email
# Response includes:
{
"success": true,
"message": "Test email(s) sent successfully to [email protected]",
"emailType": "all",
"results": [
{ "type": "purchase-confirmation", "status": "sent" },
{ "type": "payment-failed", "status": "sent" },
// ... all templates
]
}
# Test only purchase confirmation
GET http://localhost:3000/api/test-email?type=purchase-confirmation
# Test with custom email
GET http://localhost:3000/api/test-email?type=new-signup&email=[email protected]
Available email types for testing:
purchase-confirmation
payment-failed
checkout-expired
subscription-cancelled
invoice-paid
new-signup
github-access-granted
all
(sends all types)
Advanced Testing
Section titled “Advanced Testing”Test with Browser:
# Open in browser for easy testing
http://localhost:3000/api/test-email?type=purchase-confirmation&email=[email protected]
Test with cURL:
curl "http://localhost:3000/api/test-email?type=all&[email protected]"
Test with JavaScript:
// Test from browser console or app
fetch('/api/test-email?type=purchase-confirmation&[email protected]')
.then(response => response.json())
.then(data => console.log(data));
2. Email Preview and Development
Section titled “2. Email Preview and Development”React Email Dev Server:
# Start email development server
bun run email:dev
# Opens on http://localhost:3001
# Live preview of all email templates
# Hot reload when templates change
Individual Template Testing:
# Test specific template with custom data
fetch('/api/test-email', {
method: 'GET',
headers: { 'Content-Type': 'application/json' }
})
3. Production Testing
Section titled “3. Production Testing”Staging Environment:
# Test on staging with real email delivery
GET https://your-staging-app.vercel.app/api/test-email?type=all&email=[email protected]
Webhook-Triggered Emails:
# Complete a test purchase to trigger real emails
# Check email delivery and formatting
# Verify all links work correctly
Email Service Integration
Section titled “Email Service Integration”1. EmailService Class
Section titled “1. EmailService Class”The EmailService
class handles all email sending:
// Located at /libs/email-service.ts
import { EmailService } from '@/libs/email-service';
// Send purchase confirmation
await EmailService.sendPurchaseConfirmation({
customerName: 'John Doe',
customerEmail: '[email protected]',
orderNumber: 'LK-2025-001',
productName: 'LaunchKit Pro',
amount: '$99.00',
// ... other required fields
});
2. Automatic Email Triggers
Section titled “2. Automatic Email Triggers”Emails are automatically sent by:
Stripe Webhooks: (/app/api/webhook/stripe/route.ts
)
- Purchase confirmation after successful payment
- Payment failed notifications
- Subscription cancellation notices
- Invoice paid confirmations
User Actions:
- New user registration
- GitHub access grants
- Support ticket responses
3. Email Configuration
Section titled “3. Email Configuration”Configure sender information in /config.ts
:
resend: {
// Email 'From' field for system emails
fromNoReply: `YourApp <[email protected]>`,
// Email 'From' field for personal emails
fromAdmin: `Your Name at YourApp <[email protected]>`,
// Support email for customer replies
supportEmail: '[email protected]',
}
Email Deliverability
Section titled “Email Deliverability”1. DNS Configuration
Section titled “1. DNS Configuration”Ensure proper DNS setup for high deliverability:
SPF Record:
v=spf1 include:_spf.resend.co ~all
DKIM Record:
resend._domainkey.yourdomain.com CNAME resend1._domainkey.resend.co
DMARC Record (Optional):
v=DMARC1; p=none; rua=mailto:[email protected]
2. Content Best Practices
Section titled “2. Content Best Practices”Subject Lines:
- Keep under 50 characters
- Avoid spam trigger words
- Use personalization:
Welcome to YourApp, ${customerName}!
Email Content:
- Include plain text version
- Use clear, scannable layouts
- Test across email clients
- Include unsubscribe links
3. Monitoring and Analytics
Section titled “3. Monitoring and Analytics”Resend Dashboard:
- Track delivery rates
- Monitor bounces and complaints
- View click-through rates
- Check spam scores
Custom Analytics:
// Track email opens/clicks in your app
const trackEmailOpen = async (emailId: string, userId: string) => {
await supabase.from('email_analytics').insert({
email_id: emailId,
user_id: userId,
event_type: 'open',
timestamp: new Date()
});
};
Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”Emails Not Sending:
# Check API key configuration
echo $RESEND_API_KEY
# Verify domain setup in Resend dashboard
# Check server logs for error messages
# Test with simple API call
Emails Going to Spam:
- Verify DNS records are correctly configured
- Check sender reputation in Resend dashboard
- Avoid spam trigger words in subject/content
- Include proper unsubscribe mechanisms
Template Rendering Issues:
# Test individual templates
bun run email:dev
# Check React Email component syntax
# Verify all props are properly typed
# Test with default values
Debug Tools
Section titled “Debug Tools”Email Testing:
// Add debug logging to EmailService
console.log('Sending email:', {
to: data.customerEmail,
subject: `Purchase Confirmed - ${data.productName}`,
template: 'purchase-confirmation'
});
Resend Logs:
- Check delivery status in Resend dashboard
- View bounce and complaint details
- Monitor API usage and limits
Advanced Features
Section titled “Advanced Features”1. Email Sequences
Section titled “1. Email Sequences”Create automated email sequences:
// Welcome series for new users
const sendWelcomeSeries = async (userId: string) => {
// Day 0: Welcome email
await EmailService.sendNewSignup(userData);
// Day 3: Getting started tips
setTimeout(() => {
EmailService.sendGettingStarted(userData);
}, 3 * 24 * 60 * 60 * 1000);
// Day 7: Feature highlights
setTimeout(() => {
EmailService.sendFeatureHighlights(userData);
}, 7 * 24 * 60 * 60 * 1000);
};
2. Email Personalization
Section titled “2. Email Personalization”Use customer data for personalization:
const personalizedEmail = {
customerName: profile.name || 'there',
accountAge: getDaysSinceSignup(profile.created_at),
totalPurchases: await getPurchaseCount(profile.id),
favoriteFeature: await getMostUsedFeature(profile.id)
};
3. A/B Testing
Section titled “3. A/B Testing”Test different email versions:
const emailVersion = Math.random() > 0.5 ? 'A' : 'B';
if (emailVersion === 'A') {
await EmailService.sendPurchaseConfirmationV1(data);
} else {
await EmailService.sendPurchaseConfirmationV2(data);
}
// Track performance in analytics
Next Steps
Section titled “Next Steps”Once your email system is configured:
- Set up Authentication - Configure user login and OAuth
- Test Complete User Journey - End-to-end testing including emails
- Configure Admin Dashboard - Monitor email delivery and user engagement
- Deploy to Production - Set up production email domain
Best Practices
Section titled “Best Practices”Development
Section titled “Development”- Always test emails before deploying
- Use the test endpoint extensively during development
- Preview emails across different devices and clients
- Keep template code clean and well-documented
Production
Section titled “Production”- Monitor delivery rates and engagement metrics
- Implement proper error handling and retry logic
- Respect user preferences and unsubscribe requests
- Maintain professional tone and branding consistency
Security
Section titled “Security”- Never include sensitive information in emails
- Use secure links with proper authentication
- Implement email verification for critical actions
- Monitor for suspicious email activity