Resend
Leave Localhost uses Resend for transactional email delivery, integrated via the @convex-dev/resend Convex component.
Leave Localhost uses Resend for transactional email
delivery, integrated via the @convex-dev/resend Convex component.
Setup
-
Create a Resend account at resend.com.
-
Get an API key from the Resend dashboard.
-
Verify a domain for production senders.
-
Set environment variables in your Convex deployment:
RESEND_API_KEY=re_... RESEND_AUTH_FROM_EMAIL=Your App <auth@yourdomain.com> RESEND_FROM_EMAIL=Your App <hello@yourdomain.com>RESEND_API_KEYandRESEND_AUTH_FROM_EMAILare required because signup verification, password reset, magic-link sign-in, and invitations send transactional auth email.
The sendEmail Facade
All emails are sent through a single function in email/index.ts:
import { sendEmail } from "./email";
await sendEmail(ctx, {
to: "user@example.com",
subject: "Your sign-in link",
html: renderedHtml,
text: plainTextFallback,
from: env.RESEND_AUTH_FROM_EMAIL,
});The facade:
- Uses
@convex-dev/resendcomponent for delivery - Falls back to
RESEND_FROM_EMAILoronboarding@resend.devif nofromis specified - Throws a
NOT_CONFIGUREDerror ifRESEND_API_KEYis missing
Sender Addresses
| Variable | Used for |
|---|---|
RESEND_AUTH_FROM_EMAIL | Required sender for auth emails: verification, password reset, magic link, invitation |
RESEND_FROM_EMAIL | Optional default sender for non-auth transactional emails |
Using a separate auth sender helps with deliverability — auth emails can use
a domain like auth@yourdomain.com to keep them distinct from marketing or
notification emails.
Delivery Tracking
Resend can send delivery status webhooks. The endpoint is registered at
POST /webhooks/resend in http.ts:
http.route({
path: "/webhooks/resend",
method: "POST",
handler: httpAction(async (ctx, request) => {
if (!env.RESEND_WEBHOOK_SECRET) {
return new Response("Resend webhook not configured", { status: 501 });
}
return await resend.handleResendEventWebhook(ctx, request);
}),
});Set RESEND_WEBHOOK_SECRET and configure the webhook URL in the Resend
dashboard to enable tracking.
Convex Component
The Resend component is registered in convex.config.ts:
import resend from "@convex-dev/resend/convex.config.js";
app.use(resend);It provides the sendEmail method used by the facade.
Next Reads
- React Email — the email preview workspace.
- Customizing Email Templates — editing templates.
React Email
The packages/email workspace provides a React Email development environment for previewing and iterating on email templates.
Customizing Email Templates
All production email templates live in packages/backend/convex/email/templates/. They are React components rendered to HTML using @react-email/render.