General
Email

Configuration

Learn how to configure Resend and set up email sending.

The starter kit uses Resend for sending emails. Resend is a modern email API designed for developers, offering excellent deliverability and a simple integration.

Setup

1. Create a Resend Account

  1. Go to Resend and create an account
  2. Navigate to the API Keys section in your dashboard
  3. Click Create API Key
  4. Give it a name (e.g., "Production" or "Development")
  5. Copy the API key (starts with re_)

2. Configure Environment Variables

Add the following environment variables to your .env file:

.env
RESEND_API_KEY=re_...
EMAIL_FROM=noreply@yourdomain.com

3. Domain Setup

To send emails from your own domain:

  1. Go to Domains in your Resend dashboard

  2. Click Add Domain

  3. Enter your domain (e.g., yourdomain.com)

  4. Add the required DNS records to verify your domain:

    • SPF Record - Authorizes Resend to send emails
    • DKIM Record - Signs emails for authentication
    • DMARC Record (optional) - Email authentication policy
  5. Wait for domain verification (usually a few minutes)

  6. Update EMAIL_FROM to use your verified domain:

.env
EMAIL_FROM=noreply@yourdomain.com

Email Functions

The email functions in lib/email automatically use your environment variables.

Basic Usage

lib/email/example.ts
import { sendEmail } from '@/lib/email';

await sendEmail({
  recipient: 'user@example.com',
  subject: 'Welcome!',
  html: '<h1>Welcome to our platform!</h1>',
  text: 'Welcome to our platform!'
});

Using Pre-built Templates

The email module exports functions for all pre-built templates:

lib/actions/signup.ts
import { sendVerifyEmailAddressEmail } from '@/lib/email';

await sendVerifyEmailAddressEmail({
  recipient: user.email,
  name: user.name,
  verificationLink: `${getBaseUrl()}/verify-email?token=${token}`
});

Retry Logic

The email service includes automatic retry logic with exponential backoff:

  • Max Attempts: 3 retries
  • Base Delay: 1 second
  • Max Delay: 10 seconds
  • Exponential Backoff: Delay doubles with each retry

Permanent errors (invalid email, auth failure) are not retried.

Error Handling

The email functions handle errors gracefully:

lib/email/example.ts
import { sendEmail } from '@/lib/email';

try {
  await sendEmail({
    recipient: 'user@example.com',
    subject: 'Test',
    html: '<p>Test</p>',
    text: 'Test'
  });
} catch (error) {
  // Error is logged automatically
  // Permanent errors are not retried
  // Transient errors are retried automatically
}

Production Configuration

For production deployments:

  1. Use a verified domain - Always use your own domain, not Resend's default
  2. Set up SPF/DKIM - Ensure DNS records are properly configured
  3. Monitor deliverability - Check Resend dashboard for bounce rates
  4. Set up webhooks (optional) - Track email events (delivered, bounced, etc.)

Environment Variables in Production

Add your environment variables in your hosting platform:

  • Vercel: Project Settings → Environment Variables
  • Railway: Variables tab
  • Other platforms: Follow their environment variable documentation

Testing

Development

For local development, you can:

  1. Use Resend's test domain: onboarding@resend.dev
  2. Check the Resend dashboard for sent emails
  3. Use React Email Preview (see Email Templates)

Testing Emails

lib/email/test.ts
import { sendVerifyEmailAddressEmail } from '@/lib/email';

// Test sending an email
await sendVerifyEmailAddressEmail({
  recipient: 'test@example.com',
  name: 'Test User',
  verificationLink: 'https://example.com/verify?token=test'
});

Rate Limits

Resend has the following rate limits:

  • Free Tier: 3,000 emails/month, 100 emails/day
  • Pro Tier: 50,000 emails/month, higher daily limits
  • Enterprise: Custom limits

Monitor your usage in the Resend dashboard to avoid hitting limits.

Best Practices

  1. Always use your own domain - Better deliverability and branding
  2. Set up DNS records correctly - SPF, DKIM and DMARC
  3. Monitor bounce rates - Remove invalid email addresses
  4. Use templates - Consistent branding and easier maintenance
  5. Handle errors gracefully - Log errors and notify admins
  6. Test before production - Verify emails look correct across clients