For the complete documentation index, see llms.txt. Prefer markdown by appending.mdto documentation URLs or sendingAccept: text/markdown.
Email delivery
Localized email delivery through Cloudflare, with typed templates, sender configuration, recipient options, and direct or queued application workflows.
The shared email integration lets server operations and background jobs send any registered template through Cloudflare Email Service. It renders the subject, HTML, and plain text in the recipient's language and submits them together for delivery.
Use it for account messages, product notifications, or follow-ups. The template guide covers composing and previewing the message; this guide covers the sender and application workflow.
Configuration
Onboard your domain to Cloudflare Email Service and finish domain verification. EMAIL_FROM defaults the sender used by the adapter. The address must be allowed by send_email.allowed_sender_addresses in wrangler.jsonc.
For EMAIL_FROM="My App <noreply@example.com>", the allowed address is noreply@example.com, without the display name. The bindings page owns this configuration. CONTACT_EMAIL is the destination for contact messages, not the sender.
Email configuration walks through sender setup, branding, reply addresses, and the difference between previews, simulated messages, and real delivery.
Usage
To send a registered template from server code, provide its recipient, variables, and language:
import { EmailTemplate, sendEmail } from "@/lib/email";
await sendEmail({
to: "reader@example.com",
template: EmailTemplate.VERIFY_EMAIL,
variables: { url: "https://app.example.com/<verification-link>" },
locale: "en",
});to accepts one address or an array. locale defaults to the base locale, and the adapter accepts optional from and replyTo. An overridden sender still needs to be allowed by the binding. Keep recipient selection on the server so a public function cannot become an arbitrary email relay.
Immediate vs queued delivery
- Direct delivery: the operation needs an immediate delivery result, such as password recovery or a contact submission.
- Queued delivery: the message should be delayed or retried separately from the customer's request.
The included account and contact messages demonstrate direct sending. The welcome message demonstrates queued delivery, with a five-minute delay and a check of the customer's current verification state before sending.
Use the included queue pattern for delayed notifications. When a message or action should happen once, add an idempotency key or a durable processed-job record as described in background jobs.
Testing
The shipped EMAIL binding has no remote: true, so local sends are simulated. Wrangler logs the message and provides local output for inspection; it does not deliver to a real inbox. pnpm email separately previews rendering and is not an inbox.
To test actual delivery, deploy with your verified sender, or deliberately configure a remote email binding following Cloudflare's local email guidance. A remote binding sends real messages.
Check one password verification, a contact submission to CONTACT_EMAIL, and the delayed welcome job. If rendering works but production delivery fails, check domain verification, sender restrictions, and Email Service logs before editing the template. If only welcome mail fails, inspect queue processing and the user's current verification state.
How is this guide?
Last updated on