DevelopmentEmail & Resend
Email system with Resend
Email system with Resend
This page gives a high-level overview of the SuitsBooks email system built on Resend and React Email.
Overview
The email system provides:
- React Email templates – responsive templates built with React.
- Resend SDK integration – direct integration with Resend’s API for reliable delivery.
- Built-in protections – rate limiting, duplicate detection, and abuse prevention.
- Email tracking – open tracking, delivery status, and click tracking.
- Database storage – all emails stored in the
emailstable for auditing and debugging. - Bulk sending – support for sending multiple emails with batch processing.
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ Application layer │
├─────────────────────────────────────────────────────────────────────┤
│ useSendEmail hook │ useSendEmailWithNotification hook │
├─────────────────────────────────────────────────────────────────────┤
│ API routes layer │
├─────────────────────────────────────────────────────────────────────┤
│ /api/email/send │ /api/email/bulk │ /api/email/track │
├─────────────────────────────────────────────────────────────────────┤
│ Core library │
├─────────────────────────────────────────────────────────────────────┤
│ lib/email/types │ lib/email/config │ lib/email/utils │
├─────────────────────────────────────────────────────────────────────┤
│ Templates │
├─────────────────────────────────────────────────────────────────────┤
│ emails/templates/* │ React Email components │
├─────────────────────────────────────────────────────────────────────┤
│ External services │
├─────────────────────────────────────────────────────────────────────┤
│ Resend API │ Supabase (emails table) │
└─────────────────────────────────────────────────────────────────────┘
Quick start
1. Environment setup
Add these environment variables to your .env file:
# required
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxxxxxxxx
# optional (with defaults)
RESEND_FROM_EMAIL=noreply@suitsbooks.com
RESEND_FROM_NAME=SuitsBooks
RESEND_REPLY_TO=support@suitsbooks.com
# development
# set to "true" to log emails instead of sending
EMAIL_TEST_MODE=false
For a full list and per-environment examples, see Email configuration.
2. Send your first email
import { useSendEmail } from "@/hooks/use-send-email";
function MyComponent() {
const { sendEmail, isLoading } = useSendEmail();
const handleSend = async () => {
const result = await sendEmail({
to: "customer@example.com",
subject: "Welcome to SuitsBooks!",
template_id: "welcome",
template_data: {
USER_NAME: "John Doe",
LOGIN_URL: "https://app.suitsbooks.com/login",
SUPPORT_EMAIL: "support@suitsbooks.com",
},
});
if (result.success) {
console.log("Email sent!", result.email_id);
}
};
return (
<button onClick={handleSend} disabled={isLoading}>
{isLoading ? "Sending..." : "Send welcome email"}
</button>
);
}
Documentation map
| Page | Description |
|------|-------------|
| Templates | Creating and using email templates. |
| Hooks | Using the useSendEmail and useSendEmailWithNotification hooks. |
| API | HTTP API endpoints reference. |
| Configuration | Environment variables and configuration options. |
| Protections | Rate limiting, validation, and abuse prevention. |
File structure
├── lib/email/
│ ├── index.ts main exports
│ ├── types.ts TypeScript types
│ ├── config.ts configuration
│ └── utils.ts helper functions
│
├── emails/
│ ├── templates/
│ │ ├── index.ts template registry
│ │ ├── base-layout.tsx
│ │ ├── welcome.tsx
│ │ ├── password-reset.tsx
│ │ ├── verification.tsx
│ │ ├── payment-reminder.tsx
│ │ └── payment-received.tsx
│ ├── invoice.tsx legacy templates
│ ├── company-invite.tsx
│ └── ...
│
├── hooks/
│ ├── use-send-email.ts
│ └── use-send-email-with-notification.ts
│
└── apps/dashboard/app/api/email/
├── send/route.ts single email endpoint
├── bulk/route.ts bulk email endpoint
├── track/route.ts tracking pixel
└── status/[email_id]/route.ts
Database schema
All sent emails are stored in the emails table:
create table public.emails (
id bigint generated by default as identity primary key,
created_at timestamp with time zone not null default now(),
email_id uuid not null default gen_random_uuid(),
subject text,
recipient_email text,
sender_email text,
body json,
status text,
user_id text,
template_id text,
replace_data json,
html_body text,
opened boolean,
delivered boolean,
request_id text,
resource_type_ref text,
resource_id_ref text,
view_key text,
company_id uuid,
constraint emails_email_id_key unique (email_id),
constraint emails_view_key_key unique (view_key)
);
For more query examples and monitoring patterns, see Email protections.
Key features
Type-safe payloads
interface SendEmailPayload {
to: string | EmailRecipient | EmailRecipient[];
subject: string;
template_id: EmailTemplateId;
template_data?: TemplateVariables;
from?: string;
reply_to?: string;
cc?: string | EmailRecipient[];
bcc?: string | EmailRecipient[];
attachments?: EmailAttachment[];
resource_type_ref?: string;
resource_id_ref?: string;
}
React Email templates
import { Html, Head, Body, Text, Button } from "@react-email/components";
export default function WelcomeEmail() {
return (
<Html>
<Head />
<Body>
<Text>Hello {"{{USER_NAME}}"}!</Text>
<Button href="{{LOGIN_URL}}">Get started</Button>
</Body>
</Html>
);
}
Resend SDK integration
const { data, error } = await resend.emails.send({
from: "SuitsBooks <noreply@suitsbooks.com>",
to: ["user@example.com"],
subject: "Hello",
react: WelcomeEmail(),
});
Best practices
- Use
template_datainstead of hard-coding – keep templates generic and pass all dynamic values from your application. - Link emails to resources – use
resource_type_refandresource_id_refto connect emails to invoices, quotes, and other records. - Handle errors gracefully – always check
result.successand show clear feedback in the UI. - Test in development – use
EMAIL_TEST_MODE=trueto log emails without sending real traffic. - Monitor rate limits – use
getRateLimitStatus()and the protections in Email protections.
Support
For questions or issues:
- Check the Resend documentation.
- Check the React Email documentation.
- Open an issue in the repository.