$npx -y skills add jackspace/ClaudeSkillz --skill cloudflare-email-routingComplete guide for Cloudflare Email Routing covering both Email Workers (receiving emails) and Send Email bindings (sending emails from Workers). Use when: setting up email routing, creating email workers, processing incoming emails, sending emails from Workers, implementing emai
| 1 | # Cloudflare Email Routing |
| 2 | |
| 3 | **Status**: Production Ready ✅ |
| 4 | **Last Updated**: 2025-10-23 |
| 5 | **Latest Versions**: postal-mime@2.5.0, mimetext@3.0.27 |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## What is Cloudflare Email Routing? |
| 10 | |
| 11 | Cloudflare Email Routing provides two complementary capabilities: |
| 12 | |
| 13 | 1. **Email Workers** - Receive and process incoming emails with custom logic (allowlists, blocklists, forwarding, parsing, replying) |
| 14 | 2. **Send Email** - Send emails from Workers to verified destination addresses (notifications, alerts, confirmations) |
| 15 | |
| 16 | Both capabilities are **free** and work together to enable complete email functionality in Cloudflare Workers. |
| 17 | |
| 18 | --- |
| 19 | |
| 20 | ## Quick Start (10 Minutes) |
| 21 | |
| 22 | ### Part 1: Enable Email Routing (Dashboard) |
| 23 | |
| 24 | **Prerequisites**: Domain must be on Cloudflare DNS |
| 25 | |
| 26 | 1. Log in to Cloudflare Dashboard → select your domain |
| 27 | 2. Go to **Email** > **Email Routing** |
| 28 | 3. Select **Enable Email Routing** → **Add records and enable** |
| 29 | - This automatically adds MX records, SPF, and DKIM to your DNS |
| 30 | 4. Create a destination address: |
| 31 | - **Custom address**: `hello@yourdomain.com` |
| 32 | - **Destination**: Your personal email (e.g., `you@gmail.com`) |
| 33 | - **Verify** the destination address via email |
| 34 | 5. ✅ Basic email forwarding is now active |
| 35 | |
| 36 | **What you just did**: Configured DNS and basic forwarding. Now let's add Workers for custom logic. |
| 37 | |
| 38 | --- |
| 39 | |
| 40 | ### Part 2: Receiving Emails with Email Workers |
| 41 | |
| 42 | #### 1. Install Dependencies |
| 43 | |
| 44 | ```bash |
| 45 | npm install postal-mime@2.5.0 mimetext@3.0.27 |
| 46 | ``` |
| 47 | |
| 48 | **Why these packages:** |
| 49 | - `postal-mime` - Parse incoming email messages (headers, body, attachments) |
| 50 | - `mimetext` - Create email messages for sending/replying |
| 51 | |
| 52 | #### 2. Create Email Worker |
| 53 | |
| 54 | Create `src/email.ts`: |
| 55 | |
| 56 | ```typescript |
| 57 | import { EmailMessage } from 'cloudflare:email'; |
| 58 | import PostalMime from 'postal-mime'; |
| 59 | |
| 60 | export default { |
| 61 | async email(message, env, ctx) { |
| 62 | // Parse the incoming message |
| 63 | const parser = new PostalMime.default(); |
| 64 | const email = await parser.parse(await new Response(message.raw).arrayBuffer()); |
| 65 | |
| 66 | console.log('From:', message.from); |
| 67 | console.log('To:', message.to); |
| 68 | console.log('Subject:', email.subject); |
| 69 | |
| 70 | // Forward to verified destination |
| 71 | await message.forward('your-email@example.com'); |
| 72 | }, |
| 73 | }; |
| 74 | ``` |
| 75 | |
| 76 | #### 3. Configure Wrangler |
| 77 | |
| 78 | Update `wrangler.jsonc`: |
| 79 | |
| 80 | ```jsonc |
| 81 | { |
| 82 | "name": "email-worker", |
| 83 | "main": "src/email.ts", |
| 84 | "compatibility_date": "2025-10-11" |
| 85 | } |
| 86 | ``` |
| 87 | |
| 88 | #### 4. Deploy and Bind |
| 89 | |
| 90 | ```bash |
| 91 | npx wrangler deploy |
| 92 | |
| 93 | # In Cloudflare Dashboard: |
| 94 | # Email > Email Routing > Email Workers |
| 95 | # Select your worker → Create route → Enter address (e.g., hello@yourdomain.com) |
| 96 | ``` |
| 97 | |
| 98 | **What you just did**: Created a Worker that logs and forwards emails. |
| 99 | |
| 100 | --- |
| 101 | |
| 102 | ### Part 3: Sending Emails from Workers |
| 103 | |
| 104 | #### 1. Configure Send Email Binding |
| 105 | |
| 106 | Update `wrangler.jsonc`: |
| 107 | |
| 108 | ```jsonc |
| 109 | { |
| 110 | "name": "my-worker", |
| 111 | "main": "src/index.ts", |
| 112 | "compatibility_date": "2025-10-11", |
| 113 | "send_email": [ |
| 114 | { |
| 115 | "name": "EMAIL", |
| 116 | "destination_address": "notifications@yourdomain.com" |
| 117 | } |
| 118 | ] |
| 119 | } |
| 120 | ``` |
| 121 | |
| 122 | **CRITICAL**: `destination_address` must be: |
| 123 | - A domain where you have Email Routing enabled |
| 124 | - A verified destination address in Email Routing settings |
| 125 | |
| 126 | #### 2. Send Email from Worker |
| 127 | |
| 128 | ```typescript |
| 129 | import { EmailMessage } from 'cloudflare:email'; |
| 130 | import { createMimeMessage } from 'mimetext'; |
| 131 | |
| 132 | export default { |
| 133 | async fetch(request, env, ctx) { |
| 134 | // Create email message |
| 135 | const msg = createMimeMessage(); |
| 136 | msg.setSender({ name: 'My App', addr: 'noreply@yourdomain.com' }); |
| 137 | msg.setRecipient('user@example.com'); |
| 138 | msg.setSubject('Welcome to My App'); |
| 139 | msg.addMessage({ |
| 140 | contentType: 'text/plain', |
| 141 | data: 'Thank you for signing up!', |
| 142 | }); |
| 143 | |
| 144 | // Send v |