Email System
Relevant source files
The following files were used as context for generating this wiki page:
The Email System manages automated user communications, providing infrastructure for sending, tracking, and managing transactional emails. It integrates Resend for delivery and React Email for template construction.
The system handles critical workflows including user registration welcomes, email address verification, and password resets. It features a robust failure tracking mechanism that monitors the delivery status of sent messages and a suppression system to handle bounces and complaints.
Sources: README.md:10-15, convex/emails.ts:20-25
Core Infrastructure
The backend leverages the @convex-dev/resend component to interface with the Resend API. The system initializes a Resend client with an event handler for processing webhooks.
Configuration and Constants
The system defines several constants to control email behavior and delivery monitoring.
| Constant | Value / Description |
|---|---|
FROM_EMAIL | Derived from RESEND_FROM_EMAIL environment variable; defaults to delivered@resend.dev. |
CHECK_SEND_RESULT_DELAY_MS | 45,000ms (45 seconds) delay before the first status check. |
CHECK_SEND_RESULT_MAX_BUDGET_MS | 20 minutes (total budget for retrying status checks). |
TEST_DOMAIN_EMAIL | delivered@resend.dev used for simulation or testing. |
Sources: convex/emails.ts:13-18, convex/emails.ts:32-37
Logic Flow: Sending Tracked Emails
When an email is sent, the system performs a "Tracked Email" operation. This operation initiates the send via Resend and immediately schedules a follow-up check to ensure terminal status is reached.
This diagram illustrates the lifecycle of an email send from the initial trigger through the background monitoring process.
Sources: convex/emails.ts:209-236, convex/emails.ts:47-65
Email Templates
The system uses react-email to create responsive, component-based templates. All templates are wrapped in a standard EmailLayout to ensure consistent branding and structure.
Shared Layout
The EmailLayout component provides the common HTML wrapper, including:
- Standard font stack and background colors.
- Header with site name and subtitle.
- Footer with account context and site description.
- Horizontal rules (
Hr) for content separation.
Sources: convex/emails/components/layout.tsx:21-57
Supported Email Kinds
The system categorizes emails into specific types defined in EMAIL_KINDS.
| Kind | Usage | Template Component |
|---|---|---|
welcome | New user onboarding. | WelcomeEmail |
verification | Email address validation. | VerifyEmailTemplate |
passwordReset | Account recovery. | ResetPasswordTemplate |
test | System testing. | Simple HTML string |
Sources: convex/emails.ts:20-25, convex/emails/welcome.tsx:9-40, convex/emails/verifyEmail.tsx:10-38
Rendering Logic
Emails are rendered into both HTML and plain text formats before transmission to ensure maximum client compatibility.
async function renderEmail(template: ReactElement) {
const [html, text] = await Promise.all([
render(template),
render(template, { plainText: true }),
]);
return { html, text };
}
Sources: convex/emails.ts:241-247
Delivery and Suppression
The system actively manages recipient status based on feedback from the delivery provider.
Event Handling
The handleEmailEvent mutation processes incoming webhooks from Resend. It specifically targets delivery failures to maintain sender reputation.
- Bounces: When an email bounces, the recipient is added to the
emailSuppressionstable. - Complaints: When a user marks an email as spam, the address is suppressed immediately.
Sources: convex/emails.ts:101-133
Suppression Schema
Suppressed addresses are stored to prevent future send attempts to invalid or hostile addresses.
| Field | Type | Description |
|---|---|---|
email | string | The recipient address (normalized). |
reason | string | Either bounced or complained. |
resendEmailId | string | The ID of the email that triggered the suppression. |
suppressedAt | number | Timestamp of the suppression entry. |
bounceType | string | Optional metadata for bounce sub-classification. |
Sources: convex/emails.ts:265-285
Failure Reporting
If checkSendResult identifies a permanent failure (status failed), the system invokes reportEmailFailure. This function redacts sensitive email addresses using the EMAIL_ADDRESS_PATTERN before logging the error to Sentry to ensure PII (Personally Identifiable Information) protection.
Sources: convex/emails.ts:222-239, convex/emails.ts:27-28
Summary
The Email System provides a resilient infrastructure for managing transactional communications. By combining React Email for design, Resend for delivery, and Convex for background monitoring and suppression, the system ensures high deliverability while protecting the platform's sender reputation through automated error reporting and recipient management.
Sources: convex/emails.ts:40-45, README.md:12-18