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
- Go to Resend and create an account
- Navigate to the API Keys section in your dashboard
- Click Create API Key
- Give it a name (e.g., "Production" or "Development")
- Copy the API key (starts with
re_)
2. Configure Environment Variables
Add the following environment variables to your .env file:
RESEND_API_KEY=re_...
EMAIL_FROM=noreply@yourdomain.comSecurity Note
Never commit your API keys to version control. Always use environment
variables and ensure .env is in your .gitignore.
3. Domain Setup
To send emails from your own domain:
-
Go to Domains in your Resend dashboard
-
Click Add Domain
-
Enter your domain (e.g.,
yourdomain.com) -
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
-
Wait for domain verification (usually a few minutes)
-
Update
EMAIL_FROMto use your verified domain:
EMAIL_FROM=noreply@yourdomain.comUsing Resend's Domain
For testing, you can use Resend's default domain:
onboarding@resend.dev. However, for production, always use your
own verified domain for better deliverability.
Email Functions
The email functions in lib/email automatically use your environment variables.
Basic Usage
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:
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 total attempts (the initial attempt and up to 2 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:
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:
- Use a verified domain - Always use your own domain, not Resend's default
- Set up SPF/DKIM - Ensure DNS records are properly configured
- Monitor deliverability - Check Resend dashboard for bounce rates
- 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
Test templates and delivery separately. A correct preview does not prove that Resend can authenticate your sender or deliver a message.
Preview templates locally
Run npm run email:dev, then open http://localhost:3001. This renders the
components in lib/email/templates/ with their PreviewProps without sending
email or calling Resend. See React Email Preview.
Verify provider delivery
- Set
RESEND_API_KEYto a development API key. - Set
EMAIL_FROMto an address on a verified domain. For an initial Resend test,onboarding@resend.devcan only send to the email address associated with your Resend account. - Start the application and trigger a real product flow such as email verification, password reset or an organization invitation.
- Confirm the request succeeds, the message appears in the Resend dashboard and the recipient receives it.
- Open the generated link and confirm that it uses the correct application URL for the environment you are testing.
Use a real product flow The repository does not include a standalone email test script. Triggering a shipped flow verifies the template, provider configuration and generated URL together.
Before production
- Use separate Resend API keys for development and production.
- Verify the production sending domain and set
EMAIL_FROMto that domain. - Add both email variables to the production deployment environment.
- Exercise verification, password reset and invitation delivery after deploy.
- Review failed requests, bounces and provider limits in the Resend dashboard.
Best Practices
- Always use your own domain - Better deliverability and branding
- Set up DNS records correctly - SPF, DKIM and DMARC
- Monitor bounce rates - Remove invalid email addresses
- Use templates - Consistent branding and easier maintenance
- Handle errors gracefully - Log errors and notify admins
- Test before production - Preview templates, then exercise real product flows against the deployed environment