Next.js
Send email with Next.js Server Actions and Route Handlers using the samva SDK.
Send email with Next.js
Use the samva
SDK directly from Next.js server code. Server Actions work well for forms, Route
Handlers work well for JSON endpoints, and both keep your API key server-side.
Samva sends from the verified sender configured on your account, so the
payload has no from field.
Install
bun add samva server-onlyCreate a server-only client module:
// lib/samva.ts
import "server-only";
import { createClient } from "samva";
const apiKey = process.env.SAMVA_API_KEY;
if (!apiKey) {
throw new Error("SAMVA_API_KEY is not set.");
}
export const samva = createClient({ apiKey });Server Action form
Next.js Server Actions let a form call server code directly:
// app/contact/actions.ts
"use server";
import { samva } from "../../lib/samva";
export async function sendContactEmail(formData: FormData) {
const email = String(formData.get("email") ?? "").trim();
const message = String(formData.get("message") ?? "").trim();
if (!email || !message) {
throw new Error("Email and message are required.");
}
const safeMessage = message.replaceAll("<", "<").replaceAll(">", ">");
await samva.messages.send({
to: [{ email }],
channel: "email",
email: {
subject: "Thanks for contacting us",
html: `<p>Thanks for reaching out.</p><p>${safeMessage}</p>`,
text: `Thanks for reaching out.\n\n${message}`,
},
});
}Use useActionState and
useFormStatus when the UI needs
pending and error state.
Route Handler endpoint
Use an App Router Route Handler for JSON clients:
// app/api/send/route.ts
import { samva } from "../../../lib/samva";
export const runtime = "edge";
export async function POST(request: Request) {
const body = (await request.json()) as { email?: unknown; message?: unknown };
const email = typeof body.email === "string" ? body.email.trim() : "";
const message = typeof body.message === "string" ? body.message.trim() : "";
if (!email || !message) {
return Response.json({ ok: false, error: "email and message are required" }, { status: 400 });
}
const safeMessage = message.replaceAll("<", "<").replaceAll(">", ">");
let result;
try {
result = await samva.messages.send({
to: [{ email }],
channel: "email",
email: {
subject: "Thanks for contacting us",
html: `<p>Thanks for reaching out.</p><p>${safeMessage}</p>`,
text: `Thanks for reaching out.\n\n${message}`,
},
});
} catch {
return Response.json({ ok: false, error: "Failed to send message." }, { status: 502 });
}
return Response.json({ ok: true, result });
}The SDK is fetch-based, so this send path can run in the Next.js Edge runtime. Choose Node instead when the surrounding handler needs Node-only database drivers, filesystem access, or other Node built-ins.
React Email
Render React Email to HTML, then send the strings with Samva:
import { render, toPlainText } from "react-email";
import { samva } from "./lib/samva";
import WelcomeEmail from "./emails/welcome";
const html = await render(<WelcomeEmail name="Ada" />);
await samva.messages.send({
to: [{ email: "ada@example.com" }],
channel: "email",
email: { subject: "Welcome", html, text: toPlainText(html) },
});See the React Email integration for the full templating workflow.
Full cookbook and example
The cookbook and example links resolve after the companion
samva-integrations PR lands.