Skip to content

Email Integration

RocketFuel includes optional Resend integration for transactional emails. This guide covers setup, sending emails, and best practices.

Prerequisites

  1. Create a Resend account
  2. Verify your domain or use the test domain
  3. Get your API key from the Resend Dashboard

Environment Variables

Terminal window
RESEND_API_KEY="re_..."

Sending Emails

The generated code includes a Resend client:

src/lib/email.ts
import { Resend } from "resend";
export const resend = new Resend(process.env.RESEND_API_KEY);

Basic Email

import { resend } from "@/lib/email";
await resend.emails.send({
from: "noreply@yourdomain.com",
to: "user@example.com",
subject: "Welcome to our app!",
html: "<p>Thanks for signing up!</p>",
});

With React Email Templates

import { resend } from "@/lib/email";
import WelcomeEmail from "@/emails/welcome";
await resend.emails.send({
from: "noreply@yourdomain.com",
to: "user@example.com",
subject: "Welcome!",
react: WelcomeEmail({ name: "John" }),
});

Common Patterns

Wrapper Function

Create a helper for consistent email sending:

import { resend } from "@/lib/email";
interface SendEmailOptions {
to: string;
subject: string;
html: string;
}
export async function sendEmail({ to, subject, html }: SendEmailOptions) {
const { error } = await resend.emails.send({
from: process.env.EMAIL_FROM!,
to,
subject,
html,
});
if (error) {
console.error("Failed to send email:", error);
throw error;
}
}

With Background Jobs

Combine with BullMQ for reliable delivery:

// Add to queue
await emailQueue.add("send", {
to: "user@example.com",
subject: "Your order shipped!",
html: "<p>Track your package...</p>",
});
// Worker processes the job
const emailWorker = new Worker("email", async (job) => {
await sendEmail(job.data);
});

Testing

Use the Resend test domain during development:

.env.development
EMAIL_FROM="onboarding@resend.dev"

Further Reading