Cloudflare Email WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
Send all WordPress email through the Cloudflare Email Sending API and log every message. Configure via wp-config.php — no admin settings.
Install
Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/avunu/wordpress-cloudflare-email/releases/download/v0.2.1/cloudflare-email.zipRoute all WordPress email through the Cloudflare Email Sending API and keep a searchable log of every message. Configured entirely through wp-config.php constants — there is no settings screen.
- Tiny surface. No admin settings; the only screen is the log viewer (Tools → Cloudflare Email), built with WordPress DataViews.
- Drop-in. Hooks
wp_mail()without redefining it — every plugin/theme that sends mail is routed automatically, with Cc/Bcc/Reply-To/custom headers/inline images preserved. - Logged. Every send (and every failure) is recorded; view, resend, or delete from the log.
- Self-updating. Pulls new versions straight from GitHub Releases.
Requirements
- WordPress 6.6+ and PHP 8.4+.
- A Cloudflare account with Email Sending enabled for your sending domain (see Cloudflare's setup guide;
npx wrangler email sending enable yourdomain.com). - A Cloudflare API token with the Email Sending permission.
Deliverability records (SPF/DKIM/DMARC) and domain onboarding are managed in Cloudflare — this plugin only sends.
Configuration
Add to wp-config.php:
// Required
define('CLOUDFLARE_EMAIL_ACCOUNT_ID', 'your-cloudflare-account-id');
define('CLOUDFLARE_EMAIL_API_TOKEN', 'token-with-email-sending-permission');
// Recommended — the From domain must be onboarded to Cloudflare Email Sending.
// (WordPress otherwise defaults to wordpress@<site-domain>, which is usually unverified.)
define('CLOUDFLARE_EMAIL_FROM', 'no-reply@your-verified-domain.com');
define('CLOUDFLARE_EMAIL_FROM_NAME', 'Your Site');
// Optional
define('CLOUDFLARE_EMAIL_LOG', false); // stop logging *successful* sends
// (failures are always logged); default true
define('CLOUDFLARE_EMAIL_LOG_RETENTION_DAYS', 30); // auto-prune window; 0 = keep forever
When the required constants are absent the plugin does nothing and WordPress mail continues through its normal transport.
If Cloudflare rejects a message (e.g. an unverified sender, or a custom header it disallows) the send is logged as failed and wp_mail() returns false — there is no silent fallback. To adjust the outgoing payload, filter it:
add_filter('cloudflare_email_payload', function (array $payload) {
unset($payload['headers']['X-Some-Header']);
return $payload;
});
Verifying
With WP-CLI:
wp cloudflare-email verify # check the API token
wp cloudflare-email send-test you@example.com
Then open Tools → Cloudflare Email to see the log entry.
Development
The log viewer is a TypeScript DataViews app bundled with rolldown; the dev shell and release build are driven by Nix (with direnv):
direnv allow # or: nix develop
composer install # PHP deps (plugin-update-checker)
npm install # JS deps (rolldown, typescript, oxlint, @wordpress/dataviews)
npm run dev # watch-build the DataViews app (rolldown --watch)
npm run build # production bundle -> build/
npm run check # oxfmt + oxlint + type-aware oxlint + tsc (the CI gate)
npm run build emits build/index.js (IIFE), build/index.asset.php (the WordPress
dependency manifest), and build/index.css (the DataViews stylesheet).
@wordpress/dataviews and its non-core deps are bundled; every other @wordpress/*
package resolves to its core wp.* global at runtime.
Linting/formatting use the OXC toolchain — oxlint (all categories
at error, plus a type-aware pass via oxlint-tsgolint) and oxfmt. npm run check
runs the full gate; npm run lint:fix / npm run format apply autofixes. The same
gate runs in CI on every push and pull request.
Build the distributable, self-contained zip (bundles vendor/ and the compiled build/):
nix build .#zip -L # -> result/cloudflare-email.zip
Releasing
Commits to main follow Conventional Commits. Release Please maintains a release PR; merging it bumps the version in composer.json, package.json, and the plugin header, updates CHANGELOG.md, tags vX.Y.Z, and the release workflow builds cloudflare-email.zip with Nix and attaches it to the GitHub Release. Client sites self-update from that asset via plugin-update-checker.
License
MIT © Avunu LLC
Releases
6 releases. Each count is every asset in that release; expand a row for the breakdown.