Send email with Remix

An action that sends and returns, with no client-side code involved.

You need a verified sending domain and an API key from Settings › API Keys. If neither exists yet, the quickstart covers both in a couple of minutes.

Install

npm i sending-sdk

Send

import type { ActionFunctionArgs } from "@remix-run/node";
import { Sending } from "sending-sdk";
 
const sending = new Sending({ apiKey: process.env.SENDING_API_KEY! });
 
export async function action({ request }: ActionFunctionArgs) {
  const form = await request.formData();
  const email = String(form.get("email"));
  const res = await sending.emails.send({
    from: "Acme <[email protected]>",
    to: email,
    subject: "Welcome",
    html: "<p>You're in.</p>",
    idempotencyKey: `welcome-${email}`,
  });
  return { id: res.id };
}

A successful call answers 202 with the message id: accepted and queued, not yet delivered. Delivery, opens, bounces and complaints arrive later, on webhooks or in the dashboard.

What changes in Remix

Actions run on the server only, so importing the SDK in a route module is safe as long as it is not also used in a component.

The thing that catches people

A double form submission is a normal user behaviour, not an edge case. Deriving the key from the form data, as above, makes the second submit a no-op instead of a second email.

Next

  • All the fields: cc and bcc, reply-to, attachments, templates, scheduling.
  • Webhooks: delivery, bounce and complaint events, signed with HMAC.
  • Domains: SPF, DKIM and MAIL FROM, and why sending is refused until they are in place.
  • MCP: the same operations as tools, when the one writing the code is an agent.

Nearby: JavaScript and TypeScript

All 30 stacks