Leave Localhost logoLeave LocalhostDocs
Emails

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

  1. Create a Resend account at resend.com.

  2. Get an API key from the Resend dashboard.

  3. Verify a domain for production senders.

  4. 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_KEY and RESEND_AUTH_FROM_EMAIL are 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/resend component for delivery
  • Falls back to RESEND_FROM_EMAIL or onboarding@resend.dev if no from is specified
  • Throws a NOT_CONFIGURED error if RESEND_API_KEY is missing

Sender Addresses

VariableUsed for
RESEND_AUTH_FROM_EMAILRequired sender for auth emails: verification, password reset, magic link, invitation
RESEND_FROM_EMAILOptional 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

On this page