Email System Setup Guide
Complete guide to configuring TinyKit Pro's email system using Resend for notifications, invitations, and password reset functionality.
Complete guide to configuring TinyKit Pro's email system using Resend for notifications, invitations, and password reset functionality.
Overview
TinyKit Pro uses Resend for email delivery with two distinct systems:
Notification Email System
- Context: Runs in Convex actions with full database access
- Templates: React Email components with database-driven theming
- Configuration: Database settings (admin configurable) + Convex API keys
- Features: Multi-channel notifications, team invitations, billing updates
Authentication Email System
- Context: Runs in auth provider context with database access
- Templates: React Email components with database-driven theming
- Configuration: Database settings (admin configurable) + API keys
- Features: Password reset, email verification, magic links with consistent branding
This dual system design ensures authentication remains secure and isolated while providing rich email capabilities for general notifications.
Prerequisites
Optional for Quick Setup:
- Resend account (free tier: 100 emails/day, 3,000/month)
- Domain access for production email verification (optional for development)
Note: As of TinyKit Pro v1.1+, the RESEND_API_KEY is optional during initial setup. The application will run without email functionality, which can be enabled later by configuring the API key. This allows developers to start immediately without external service dependencies.
1. Create Resend Account
- Sign Up: Go to resend.com and create a free account
- Verify Email: Complete email verification process
- Dashboard Access: Access your Resend Dashboard
2. Get API Keys
Development API Key
- Navigate to API Keys: Go to API Keys
- Create API Key: Click "Create API Key"
- Key Details:
- Name: "TinyKit Pro Development"
- Permission: "Full access" (for development)
- Copy Key: Copy the API key (starts with
re_)
Environment Configuration
Add the API key to the Convex environment:
# Add to Convex environment (all email functionality)
npx convex env set RESEND_API_KEY re_your_api_key_here
npx convex env set RESEND_TEST_MODE true # Enable test mode for developmentNote: RESEND_API_KEY is set in the Convex environment only—not in .env.local. Both notification emails and authentication emails (password reset, magic links) use the Convex backend.
Email Configuration: Support email, domain, and site URL are configured through the database via Admin Panel → Site Settings → Email Configuration.
Optional Setup: If you skip this step during initial setup, the application runs with email features disabled. Email operations log warnings but don't crash the application. You can add the RESEND_API_KEY later when ready.
See Environment Variables Reference for complete configuration details.
3. Database Email Configuration
Email settings are now stored in the database and can be configured through the admin interface:
Admin Panel Configuration
- Access Admin Panel: Navigate to
/admin(requires admin role) - Site Settings: Go to "Site Settings" section
- Email Configuration: Find the "Email Configuration" card
- Configure Settings:
- Support Email: Reply-to address for all system emails
- Support Email Name: Display name in email headers
- Resend Domain: Your verified domain for sending emails (e.g.,
yourdomain.com) - Site URL: Base URL for email links and redirects
Default Values
During database seeding, default values are set from convex/seeds/siteDefaults.ts:
// Email configuration defaults
supportEmail: "support@example.com",
supportEmailName: "TinySaaS Support",
resendDomain: "tinykit.dev",
siteUrl: "http://localhost:3000",Runtime Updates
- Immediate Effect: Changes take effect immediately without restarting
- Consistent Branding: All email templates use database settings
- Environment Independent: No restart required for configuration changes
4. Development Email Testing
Test Mode Behavior
In development, Resend automatically operates in test mode:
- Test Addresses: Emails are sent to special test addresses
- No Real Delivery: Real users won't receive test emails
- Dashboard Visibility: All emails appear in Resend dashboard
- Delivery Simulation: Test different delivery scenarios
Test Email Addresses
The notification system uses these validated test addresses:
// Available test email options
delivered@resend.dev // Simulates successful delivery
bounced@resend.dev // Simulates email bounce
complained@resend.dev // Simulates spam complaintTesting Email Functionality
Password Reset Testing
# Test password reset flow
1. Go to http://localhost:3000/auth/sign-in
2. Click "Forgot password?"
3. Enter any email address
4. Check Resend dashboard for delivered email
5. Use OTP code from email to reset passwordNotification System Testing
# Test admin notifications
1. Go to /admin/notifications
2. Create test notification with email delivery
3. Select test email address from dropdown
4. Send notification
5. Check Resend dashboard for deliveryTeam Invitation Testing
# Test team invitations
1. Create or join a team as admin/owner
2. Go to team member management
3. Send invitation to test email
4. Check Resend dashboard for invitation email4. Email Templates
Template System Overview
TinyKit Pro uses React Email with database-driven theming:
emails/
├── common/
│ ├── Layout.tsx # Main email layout with theme support
│ ├── Header.tsx # Email header component
│ └── Footer.tsx # Email footer component
├── GeneralNotificationEmail.tsx
├── TeamInvitationEmail.tsx
├── WelcomeMessageEmail.tsx
├── BillingUpdateEmail.tsx
└── [other templates].tsxTheme Integration
Templates automatically adapt to your site's theme colors:
// EmailLayout automatically applies database theme colors
<EmailLayout
themeColors={themeColors} // From database
preview="Welcome to TinyKit Pro"
headerTitle="Welcome!"
>
<Section className="bg-primary/10 border border-primary">
<Text className="text-primary">Welcome message</Text>
</Section>
</EmailLayout>Preview System
Test templates with live preview:
# Start development server
bun dev
# Go to admin notifications panel
# Select notification type to see live email preview
# Changes update in real-time5. Production Setup
Domain Verification (Recommended)
For production, verify your domain for better deliverability:
- Add Domain: Go to Domains in Resend dashboard
- Enter Domain: Add your domain (e.g.,
yourdomain.com) - DNS Configuration: Add the provided DNS records:
Type: TXT
Name: @
Value: resend-domain-verification=abc123...
Type: MX
Name: @
Value: 10 mail.resend.com
Type: TXT
Name: @
Value: "v=spf1 include:_spf.resend.com ~all"
Type: CNAME
Name: resend._domainkey
Value: resend._domainkey.resend.com- Verify Domain: Click "Verify domain" after DNS records are active
Production API Key
Create a separate API key for production:
- Create Production Key:
- Name: "TinyKit Pro Production"
- Permission: "Sending access" (more restrictive)
- Environment Variables: Use in production environment only
# Production environment variables
RESEND_API_KEY=re_production_api_key_here
EMAIL_FROM="Your App <noreply@yourdomain.com>"
# Convex production environment
npx convex env set RESEND_API_KEY re_production_api_key_here --prod
npx convex env set EMAIL_FROM "Your App <noreply@yourdomain.com>" --prod
npx convex env set SITE_URL https://yourdomain.com --prodEmail From Address
Use your verified domain for the from address:
# Development (can use any address)
EMAIL_FROM="TinyKit Pro <noreply@example.com>"
# Production (use verified domain)
EMAIL_FROM="Your App <noreply@yourdomain.com>"6. Email System Features
Notification System
Multi-channel notifications with email delivery:
// Send notification with email
await sendNotificationToAllUsersAdmin({
type: "general_notification",
title: "System Update",
message: "We've updated our platform with new features",
deliveryChannels: ["in-app", "email"],
emailTemplate: "GeneralNotificationEmail",
testEmail: "delivered@resend.dev", // In development
});Password Reset System
Secure OTP-based password reset:
- 8-digit codes: Cryptographically secure random codes
- 10-minute expiration: Time-limited for security
- HTML templates: Beautiful, responsive email design
- Multiple access points: Sign-in page, user settings, direct URL
Team Invitations
Email-based team invitations:
- Role-specific: Invitation includes role information
- Secure links: One-time use invitation links
- 7-day expiration: Invitations expire automatically
- Responsive design: Works on all email clients
7. Email Analytics & Monitoring
Resend Dashboard
Monitor email performance:
- Email List: View all sent emails at resend.com/emails
- Delivery Status: Check delivered, bounced, complained status
- Open Rates: Track email open rates (if enabled)
- Click Tracking: Monitor link clicks (if enabled)
Application Monitoring
Monitor email system health:
# View email-related logs
npx convex logs --tail | grep "email\|resend"
# Check notification delivery status
# Use admin notification history to see delivery trackingPerformance Metrics
Key metrics to monitor:
- Delivery Rate: Percentage of emails successfully delivered
- Bounce Rate: Percentage of emails that bounced
- Open Rate: Percentage of delivered emails opened
- Response Time: Time between sending and delivery
8. Email Best Practices
Content Guidelines
- Clear Subject Lines: Descriptive and action-oriented
- Concise Content: Keep emails focused and scannable
- Strong CTAs: Clear call-to-action buttons
- Mobile-First: Design for mobile email clients
- Brand Consistency: Use consistent colors and styling
Technical Best Practices
- Template Testing: Test templates across different email clients
- Fallback Content: Provide plain text alternatives
- Image Optimization: Optimize images for email
- Link Validation: Ensure all links work correctly
- Unsubscribe Options: Include unsubscribe links where required
Deliverability Best Practices
- Domain Authentication: Use verified domains for sending
- List Hygiene: Remove bounced and invalid addresses
- Sending Reputation: Maintain good sender reputation
- Content Quality: Avoid spam triggers in content
- Engagement: Monitor and improve engagement rates
9. Troubleshooting
Common Issues
Emails not being sent in development
# Check Convex environment variables
npx convex env list | grep RESEND
# Solution: Ensure API key is set in Convex environment
npx convex env set RESEND_API_KEY re_your_api_key_here
# Note: If RESEND_API_KEY is not configured, email features are disabled
# You'll see log messages like:
# "Skipping Resend sync - RESEND_API_KEY not configured"
# This is expected behavior when running without email configurationPassword reset emails not working
# Check Convex environment configuration
npx convex env list | grep RESEND
# Solution: Ensure RESEND_API_KEY is set in Convex environment:
npx convex env set RESEND_API_KEY re_your_api_key_here
# Email configuration (support email, domain) is managed via admin panel:
# Go to /admin → Site Settings → Email ConfigurationEmail configuration issues
# Email configuration is now managed via admin panel
# Go to /admin → Site Settings → Email Configuration
# Configure:
# - Support Email: Reply-to address for system emails
# - Support Email Name: Display name in email headers
# - Resend Domain: Your verified domain (e.g., yourdomain.com)
# - Site URL: Base URL for email linksTest emails going to real users
# Check test mode configuration
# Solution: Verify using test email addresses
# delivered@resend.dev, bounced@resend.dev, complained@resend.devProduction emails not being delivered
# Check domain verification status
# Solution: Complete domain verification in Resend dashboard
# Add all required DNS records and wait for verificationTemplate colors not matching site theme
# Check theme color integration
# Solution: Verify themeColors prop is passed to EmailLayout
# Ensure site branding is configured in admin settingsDebug Commands
# Test email template rendering
cd emails && npx tsx renderTemplate.ts
# View Resend dashboard
bun email:dev
# Monitor email delivery
npx convex logs --tail | grep "email"
# Check environment variables
npx convex env listPerformance Issues
Slow email delivery
- Check: Resend API status and rate limits
- Solution: Verify API key permissions and account status
- Monitor: Email queue processing in application logs
High bounce rates
- Check: Email address validation and list quality
- Solution: Implement better email validation
- Monitor: Bounce rate trends in Resend dashboard
10. Advanced Configuration
Custom Email Templates
Create new email templates:
// emails/CustomEmail.tsx
import { EmailLayout } from "./common/Layout";
interface CustomEmailProps {
title: string;
message: string;
recipientEmail: string;
themeColors?: ThemeColors;
}
export const CustomEmail = ({
title,
message,
recipientEmail,
themeColors
}: CustomEmailProps) => {
return (
<EmailLayout
preview={title}
headerTitle="Custom Notification"
recipientEmail={recipientEmail}
themeColors={themeColors}
>
<Section className="bg-card border border-border rounded-lg p-6">
<Text className="text-card-foreground text-xl font-bold">
{title}
</Text>
<Text className="text-card-foreground text-base">
{message}
</Text>
</Section>
</EmailLayout>
);
};Webhook Integration
Set up Resend webhooks for advanced tracking:
- Configure Webhooks: In Resend dashboard settings
- Handle Events: Process delivery, bounce, and complaint events
- Update Database: Sync delivery status with notification records
Rate Limiting
Handle rate limits gracefully:
// Implement retry logic for rate limits
const sendEmailWithRetry = async (emailData) => {
try {
return await resend.sendEmail(ctx, emailData);
} catch (error) {
if (error.message.includes("rate limit")) {
// Wait and retry
await new Promise((resolve) => setTimeout(resolve, 1000));
return await resend.sendEmail(ctx, emailData);
}
throw error;
}
};