Email Setup
EmDash uses email for magic link login, user invites, and account recovery. A provider delivers the mail: either the SMTP transport built into EmDash or a provider plugin.
This guide covers how the email pipeline works, what you get out of the box in development, and how to wire up a real provider for production.
How Email Delivery Works
Section titled “How Email Delivery Works”A single active provider delivers all outgoing mail. If no provider is active, features that need email are unavailable, and invite links must then be copied and shared manually from the Users page.
You can see the current state under Settings → Email in the admin: whether a provider is active, which provider it is, and a send test email button that exercises the full pipeline.
Development: Built-in Console Provider
Section titled “Development: Built-in Console Provider”In development (astro dev), EmDash auto-activates a built-in console provider when no other provider is active. It does not send anything — it logs each email to the terminal and keeps the last 100 messages in memory.
That means magic links and invites work out of the box in dev: request a magic link, then copy the URL from your terminal output. You can also list captured emails at the dev-only endpoint GET /_emdash/api/dev/emails (and clear them with DELETE).
If Settings → Email still shows the console after you add a provider plugin or set up SMTP, select that provider there and save.
The console provider is dev-only and never runs in production builds.
Production: Built-in SMTP transport
Section titled “Production: Built-in SMTP transport”If you have SMTP credentials (for example Brevo, Office 365, Fastmail, Amazon SES, or your own mail server), EmDash can send through them without a plugin. The transport requires TLS before it authenticates, supports AUTH PLAIN and AUTH LOGIN, and refuses port 25.
Configure it in one of two ways:
- In the admin: open Settings → Email, choose SMTP, fill in the server details, and save. Saving stores the settings in the database and selects SMTP. EmDash encrypts the password with
EMDASH_ENCRYPTION_KEY, so that key must be set. Settings saved in the admin take precedence over environment variables, so change the password in the admin when you rotate it. - With environment variables: set the following variables in the server’s process environment. On Cloudflare, use
wrangler secret put, and.envfor local development. On Node, neitherastro devnor the built server loads.env, so export the variables or start the server withnode --env-file=.env. See Secrets & Key Management.
| Variable | Example | Notes |
|---|---|---|
EMAIL_SMTP_HOST |
smtp.example.com |
Required |
EMAIL_SMTP_PORT |
587 |
Optional; defaults to 587. Use 465 for implicit TLS |
EMAIL_SMTP_USER |
you@example.com |
Required; the SMTP login |
EMAIL_SMTP_PASS |
your-smtp-password |
Required; store it as a secret |
EMAIL_SMTP_SECURE |
tls or starttls |
Optional; port 465 uses tls, every other port uses starttls |
EMAIL_SMTP_FROM |
My Site <noreply@example.com> |
Optional default sender |
EMAIL_SMTP_FROM_NAME |
My Site |
Optional display name for EMAIL_SMTP_FROM_EMAIL |
EMAIL_SMTP_FROM_EMAIL |
noreply@example.com |
Optional sender address; takes precedence over EMAIL_SMTP_FROM |
EMAIL_SMTP_REPLY_TO |
hello@example.com |
Optional Reply-To address |
Without a sender variable, EmDash sends from EMAIL_SMTP_USER. If your SMTP login is not an email address, set EMAIL_SMTP_FROM_EMAIL or EMAIL_SMTP_FROM, or delivery fails with Invalid sender address for SMTP delivery. Settings → Email asks for a sender email in that case before it saves.
When the environment variables are complete, EmDash sends through SMTP unless an email provider plugin is active or another provider is selected under Settings → Email. To keep using SMTP alongside a provider plugin, select SMTP there and save.
On Cloudflare Workers, the transport needs the nodejs_compat compatibility flag. See Cloudflare deployment.
Production: Install a Provider Plugin
Section titled “Production: Install a Provider Plugin”Cloudflare Workers
Section titled “Cloudflare Workers”On Cloudflare, use the cloudflareEmail() plugin from @emdash-cms/cloudflare/plugins. It sends through Cloudflare Email Sending over a send_email Worker binding, so it needs no external account or API key. The Cloudflare deployment guide walks through onboarding the sender domain, adding the binding, and registering the plugin.
Node and other platforms
Section titled “Node and other platforms”The community-maintained emdash-smtp plugin family covers generic SMTP plus hosted providers, including Amazon SES, Brevo, Mailgun, Postmark, Resend, SendGrid, Zoho, and more.
pnpm add emdash-smtpThe following configuration registers the plugin with EmDash:
import { defineConfig } from "astro/config";import emdash from "emdash/astro";import { emdashSmtp } from "emdash-smtp";
export default defineConfig({ integrations: [ emdash({ // ...your database/storage config plugins: [emdashSmtp()], }), ],});Provider credentials are configured through the plugin’s own settings — see its README for the provider matrix and setup details.
Where provider credentials live
Section titled “Where provider credentials live”Provider plugins declare their API keys and passwords as plugin settings. Enter them on the plugin’s settings page in the admin; EmDash stores them in the database alongside other plugin settings, and rotating a key means pasting the new value there. Secrets & Key Management describes the storage and its caveats.
Whether a plugin can read a deployment secret (wrangler secret put, .env) instead depends on its format, so follow its README. Sandboxed plugins cannot access process.env or platform bindings. A native plugin can read process.env; it must not use import.meta.env, which is inlined at build time and bakes the build machine’s value into the bundle.
Selecting a Provider and Testing
Section titled “Selecting a Provider and Testing”-
Install and activate the provider plugin, then open Settings → Email in the admin.
-
If more than one provider plugin is installed, pick the active one there — only one delivers at a time.
-
Use Send test email to verify the full pipeline end to end. The result surfaces delivery errors directly, which is the fastest way to debug credentials.
Troubleshooting
Section titled “Troubleshooting”- “No email provider is configured”: no provider is active. Configure SMTP or activate a provider plugin, then select it in Settings → Email.
- Magic links / invites silently unavailable — same cause. Without a provider, the Users page still creates invites, but you must copy the invite link manually.
- Works in dev, fails in production — dev uses the built-in console provider, which masks a missing production provider. Check Settings → Email on the deployed site.
- Emails land in spam — configure SPF/DKIM/DMARC for your sending domain at your email provider; this is provider-side, not an EmDash setting.
Related
Section titled “Related”- Authentication — magic links, invites, and recovery flows that rely on email
- Email hooks reference —
email:beforeSend,email:deliver,email:afterSend