EmDash CMS email-provider plugin that delivers transactional email through the native Cloudflare Email Sending Workers binding. No API token required — auth happens via the binding.
Why this plugin? If your EmDash Worker already runs on Cloudflare, this is one less third-party dependency, one less API key to manage, and one less HTTP hop.
- EmDash
>= 0.5.0 - A Cloudflare Workers deployment (this is a trusted-mode plugin — see Caveats)
- A domain onboarded for Cloudflare Email Sending (see Setup)
npm install emdash-plugin-cloudflare-email
# or pnpm add emdash-plugin-cloudflare-emailnpx wrangler email sending enable yourdomain.com…or use the Cloudflare dashboard: Compute & AI → Email Service →
Email Sending → Onboard Domain. This adds SPF / DKIM / DMARC records to
your zone (DNS propagates in 5–15 min). To avoid touching SPF on a domain
you already use for human mail (e.g. Google Workspace), onboard a subdomain
like mail.yourdomain.com instead — the plugin's From address then
becomes noreply@mail.yourdomain.com.
The binding name must be EMAIL in this release (configurable in a
future version — see Roadmap).
import { defineConfig } from 'astro/config'
import emdash from 'emdash/astro'
import cloudflareEmail from 'emdash-plugin-cloudflare-email'
export default defineConfig({
integrations: [
emdash({
plugins: [cloudflareEmail()],
}),
],
})Navigate to EmDash Admin → Cloudflare Email and enter your From
address — for example Your App <noreply@yourdomain.com>. Save and use
the Send Test Email button to verify delivery.
That's it. EmDash's email:deliver hook is now wired to the binding —
invitations, magic links, password recovery, and any custom plugin emails
will route through Cloudflare.
- Trusted-mode only. The plugin uses the Workers
send_emailbinding, which is only accessible to plugins running in the host Worker isolate (plugins: []inastro.config.mjs). Sandboxed plugins (sandboxed: []) run in isolated V8 isolates without access to host bindings — install this plugin in trusted mode. - Astro 6 +
@astrojs/cloudflarev13+ is required, because the plugin usesimport { env } from 'cloudflare:workers'to access the binding. - Domain onboarding is irreducible. Cloudflare needs to know which domain you're allowed to send from before you can send. There's no way to skip step 1.
bindingoption to override the binding name fromEMAIL(e.g.cloudflareEmail({ binding: 'NOTIFY_EMAIL' }))- Attachment support (currently only
to/from/subject/html/text/cc/bcc/replyTopass through) - Restricted-binding support (e.g.
allowed_sender_addresses)
PRs welcome.
MIT © Velvee
{ "send_email": [ { "name": "EMAIL" } ] }