Resend transactional email for Next.js SaaS
Email is the integration most templates either skip or get half-right. Self-hosted SMTP is a deliverability minefield, transactional providers vary wildly in DX, and React-side template authoring used to require a separate render pipeline. Resend pairs a clean API with React Email so transactional mail in 2026 is a config-and-template exercise, not a multi-week project. All four BoilerlyKit templates lean on it for different reasons.
Transactional vs marketing, why the split matters
Transactional mail is one-to-one and triggered by user action: invitations, receipts, password resets, alerts. Marketing mail is one-to-many and triggered by you: newsletters, campaigns, drips. The two have different deliverability profiles (transactional reaches inbox far more reliably), different compliance requirements (CAN-SPAM and GDPR rules differ), and usually different providers.
Resend is positioned as a transactional-first provider, which is the right fit for the boilerplate use cases. For marketing, teams typically pair it with a separate tool (Loops, customer.io, Beehiiv) or use Resend's broadcast features when the volume is small. SaaSForge Core's invitation flow, AI's billing receipts, and Agency's contact-form notifications all sit on the transactional side.
What each template uses Resend for
SaaSForge Core uses Resend the heaviest: workspace invitation emails (a 'You've been invited to {workspace} by {inviter}' template), ownership transfer notifications, member-removed alerts, billing failure notifications, and 2FA recovery code delivery on demand. It is the owning product for this feature page because the email surface is product-critical, not auxiliary.
SaaSForge AI uses Resend for billing receipts on subscription events and credit-low warnings before usage runs out. SaaSForge Agency uses Resend for contact-form lead notifications to the agency's inbox plus an optional confirmation to the prospect. SaaSForge Starter does not require Resend in its minimal form, Supabase Auth's magic links go through Supabase's own email layer, but the integration shape is documented for buyers who want branded magic links via Resend.
React Email templates and the sending API
Templates live as React components in `emails/`, using @react-email/components for tables, buttons, and layouts that render correctly in Outlook and Gmail alike. The same component renders in a preview server during local dev (so you can iterate the design without sending real emails) and serializes to HTML at send time.
Sending is a single API call: build the React component, pass it to Resend's `send()`, and let the SDK serialize and dispatch. Idempotency keys are passed when the trigger is a retryable webhook event (Stripe billing receipts especially) so retried webhooks do not send duplicate emails.
import { Resend } from "resend";
import { InvitationEmail } from "@/emails/invitation";
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: "Workspace <invites@yourdomain.com>",
to: invitee.email,
subject: `You've been invited to ${workspace.name}`,
react: InvitationEmail({
workspaceName: workspace.name,
inviterName: inviter.name,
acceptUrl: `https://app.example.com/invites/${token}`,
}),
});Deliverability basics that matter on day one
Three DNS records do most of the work: SPF (lists which servers are allowed to send for your domain), DKIM (cryptographic signature so receivers can verify the message was not tampered with), and DMARC (tells receivers what to do when SPF or DKIM fail). Resend's dashboard walks you through adding the records to your DNS; without them, your transactional mail lands in spam at Gmail and gets bounced at corporate gateways.
Bounces and complaints are real: a customer enters a typo'd email, an invite to an ex-employee bounces, a recipient clicks 'spam'. Resend webhooks fire on these events so you can mark the address invalid in your database and stop sending to it. SaaSForge Core's invitation flow ships a webhook handler that flips a `delivery_status` column when the bounce hits, so a re-send to a known-bad address fails fast in the UI.