React Email7 min read

React Email + Resend: Production Checklist for Next.js

A practical pre-flight checklist for sending reliable transactional email in Next.js using React Email and Resend: env vars, validation, deliverability, idempotency, and tests.

R

React Emails Pro

February 25, 2026

Shipping emails isn't hard. Shipping emails that are reliable, secure, and don't land in spam is where teams lose weeks.

This is a practical checklist for using React Email with Resend in a Next.js app - the stuff you actually need before you call it production.

The baseline stack

  • Next.js (App Router)
  • React Email for template rendering
  • Resend as the SMTP/API provider
npm install resend react-email @react-email/components
If you're already sending emails via SMTP, you can still use React Email for rendering HTML. Resend just gives you a fast, friendly API + solid deliverability defaults.

1) Render server-side (and keep the client out of it)

The safest setup is: render and send emails on the server only. Don't bundle templates into client components.

app/api/email/welcome/route.ts
import { Resend } from "resend";
import WelcomeEmail from "@/emails/welcome";

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(req: Request) {
  const { email, name } = await req.json();

  const { error } = await resend.emails.send({
    from: "Acme <hello@acme.com>",
    to: email,
    subject: `Welcome, ${name}!`,
    react: WelcomeEmail({ name }),
  });

  if (error) return Response.json({ error }, { status: 500 });
  return Response.json({ ok: true });
}

2) Environment variables: be strict

Production email failures are usually boring: missing env vars, wrong from address, or secrets in the wrong place.

  • RESEND_API_KEY only on the server
  • A verified sending domain (not a random Gmail)
  • Separate dev and prod "from" names to avoid confusion
Add a hard startup check so your app fails fast in prod. Silent misconfiguration is how you discover email is broken… from a customer.
lib/env.ts
export function requireEnv(name: string) {
  const value = process.env[name];
  if (!value) throw new Error("Missing env var: " + name);
  return value;
}

export const RESEND_API_KEY = requireEnv("RESEND_API_KEY");

3) Validate inputs and props

The email template is code - treat its props like an API contract. Validate them before sending.

lib/email/props.ts
import { z } from "zod";

export const welcomeEmailSchema = z.object({
  email: z.string().email(),
  name: z.string().min(1).max(80),
});

export type WelcomeEmailInput = z.infer<typeof welcomeEmailSchema>;

4) Deliverability basics (do these or don't bother)

  • Set up SPF and DKIM for your domain
  • Add DMARC (start with p=none, then tighten)
  • Use a consistent from address like hello@yourdomain.com
  • Include a plain-text fallback if your setup requires it
Don't ship transactional email from a free mailbox domain. It screams "spam" and you'll pay for it in deliverability.

5) Make sends idempotent (avoid double emails)

Most duplicate emails come from retries: webhook delivery, background jobs, users double-clicking, or serverless replays.

Tie each send to a unique business event (userId + eventId) and store a send record before you hit the provider.

Minimal pattern

  • Generate a deterministic key (ex: welcome:{userId})
  • Check DB: already sent? return early
  • Write "sending" state
  • Send
  • Write "sent" state + provider message id

6) Test what matters: rendering and links

You don't need a perfect email test suite. You need a few high-signal checks that prevent embarrassing regressions.

  • Snapshot the rendered HTML (basic regression coverage)
  • Assert every CTA link exists and uses HTTPS
  • Assert the preview text is present (it affects opens)
emails/__tests__/welcome.test.tsx
import { render } from "@react-email/render";
import WelcomeEmail from "../welcome";

test("welcome email renders a dashboard link", () => {
  const html = render(WelcomeEmail({ name: "Iso", loginUrl: "https://acme.com" }));
  expect(html).toContain("https://acme.com");
});

Production quick-check (copy/paste)

  • Domain verified + SPF/DKIM/DMARC configured
  • API routes are server-only; no templates in the client bundle
  • Input validation on every send
  • Idempotency key for every transactional email
  • At least one render/link test per template

Recommended

SaaS Essentials Pack

21+ Templates · 60+ Variations. One-time purchase, lifetime updates.

$19.95$9.95Get it

If you want the fast path: start with a small set of battle-tested templates (welcome, verification, password reset, invoice, trial ending) and iterate from there.

R

React Emails Pro

Team

Building production-ready email templates with React Email. Writing about transactional email best practices, deliverability, and developer tooling.

Production-ready templates

Pick from 9 template packs built with React Email. One-time purchase, lifetime updates, tested across every major email client.

Browse all templates