<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: nonozone</title>
    <description>The latest articles on DEV Community by nonozone (@nonozone).</description>
    <link>https://dev.to/nonozone</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3856736%2F150e0c8b-0ade-49bc-8f15-958996c85ea4.jpg</url>
      <title>DEV Community: nonozone</title>
      <link>https://dev.to/nonozone</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nonozone"/>
    <language>en</language>
    <item>
      <title>The part Cloudflare Email Routing doesn't solve — and how I fixed it</title>
      <dc:creator>nonozone</dc:creator>
      <pubDate>Thu, 02 Apr 2026 04:42:53 +0000</pubDate>
      <link>https://dev.to/nonozone/the-part-cloudflare-email-routing-doesnt-solve-and-how-i-fixed-it-5jh</link>
      <guid>https://dev.to/nonozone/the-part-cloudflare-email-routing-doesnt-solve-and-how-i-fixed-it-5jh</guid>
      <description>&lt;p&gt;Cloudflare Email Routing is genuinely good. Free, reliable, zero infrastructure to manage. You point your MX records at Cloudflare, configure a few rules, and emails sent to &lt;code&gt;support@yourdomain.com&lt;/code&gt; start appearing in your Gmail inbox within minutes.&lt;/p&gt;

&lt;p&gt;If all you need is to &lt;strong&gt;receive&lt;/strong&gt; email at a custom domain, it's hard to beat.&lt;/p&gt;

&lt;p&gt;The problem starts when you hit reply.&lt;/p&gt;




&lt;h2&gt;
  
  
  What forwarding actually does
&lt;/h2&gt;

&lt;p&gt;When Cloudflare forwards a message from &lt;code&gt;support@yourdomain.com&lt;/code&gt; to your personal Gmail, it doesn't just move the email. It rewrites the envelope.&lt;/p&gt;

&lt;p&gt;The original SMTP transaction looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight email"&gt;&lt;code&gt;&lt;span class="nt"&gt;MAIL FROM&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="na"&gt; customer@example.com&lt;/span&gt;
&lt;span class="nt"&gt;RCPT TO&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="na"&gt; support@yourdomain.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After forwarding, the message arrives in your Gmail with extra headers like &lt;code&gt;X-Forwarded-To&lt;/code&gt; and &lt;code&gt;X-Original-To&lt;/code&gt; that record where it originally went. But your Gmail client doesn't read those headers. It sees one thing: this email arrived at your Gmail address.&lt;/p&gt;

&lt;p&gt;So when you hit reply, your email client does the obvious thing — it replies &lt;strong&gt;from your Gmail address&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your customer, who wrote to &lt;code&gt;support@yourdomain.com&lt;/code&gt;, now gets a reply from &lt;code&gt;yourname@gmail.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's the gap. Cloudflare solved receiving. Nobody solved replying.&lt;/p&gt;




&lt;h2&gt;
  
  
  The obvious workarounds (and why they fall short)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Add a "Send As" alias in Gmail&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gmail lets you add custom &lt;code&gt;From&lt;/code&gt; addresses via SMTP. So you add &lt;code&gt;support@yourdomain.com&lt;/code&gt; as a Send As alias, pointing at a transactional SMTP provider.&lt;/p&gt;

&lt;p&gt;This works — until you have more than one or two addresses. When you're managing &lt;code&gt;support@&lt;/code&gt;, &lt;code&gt;sales@&lt;/code&gt;, &lt;code&gt;admin@&lt;/code&gt;, &lt;code&gt;billing@&lt;/code&gt; across two or three domains, you now have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manually pick the correct From address every time you reply&lt;/li&gt;
&lt;li&gt;Remember which address the customer originally wrote to&lt;/li&gt;
&lt;li&gt;Hope you don't reply from the wrong one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At some point you will mis-send. A &lt;code&gt;support@&lt;/code&gt; customer gets a reply from &lt;code&gt;founder@&lt;/code&gt;. A &lt;code&gt;sales@&lt;/code&gt; prospect gets a reply from your personal address. The professional illusion collapses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Set up separate mailboxes per address&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the traditional solution — buy a Google Workspace seat (or Fastmail, or Zoho) for each address. It works, but now you're paying per identity, not per person, and you're context-switching between inboxes all day.&lt;/p&gt;

&lt;p&gt;If your address count grows faster than your headcount — which is common for small studios, agencies, and solo operators — this gets expensive fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  What actually needs to happen
&lt;/h2&gt;

&lt;p&gt;The root problem is that forwarded email loses its routing context by the time it reaches your client. To reply correctly, something needs to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Preserve&lt;/strong&gt; the original recipient address when forwarding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read&lt;/strong&gt; that context when you hit reply&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewrite the envelope&lt;/strong&gt; on outbound — so the SMTP &lt;code&gt;MAIL FROM&lt;/code&gt; and the visible &lt;code&gt;From:&lt;/code&gt; header show &lt;code&gt;support@yourdomain.com&lt;/code&gt;, not your personal address&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Step 3 is the key one. It's called &lt;strong&gt;envelope rewriting&lt;/strong&gt;, and it's what makes the difference between "email forwarding" and "identity routing."&lt;/p&gt;

&lt;p&gt;The flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer
  → support@yourdomain.com
  → Cloudflare Email Routing (inbound MX)
  → Relay layer (preserves routing context in headers)
  → Your working inbox (Gmail / Outlook / Apple Mail)

You hit reply
  → Mail client sends to relay's SMTP
  → Relay reads X-Original-To header
  → Relay rewrites MAIL FROM to support@yourdomain.com
  → Customer receives reply from support@yourdomain.com ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your client sees one SMTP connection. You configure it once. After that, every reply automatically goes out from whatever address the original email was sent to — no manual selection, no switching, no mistakes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building this
&lt;/h2&gt;

&lt;p&gt;I run a small one-person studio with a few projects, each with its own domain. I got tired of either paying per mailbox or manually managing Send As aliases. So I built a relay layer that sits between Cloudflare Email Routing and my working inbox.&lt;/p&gt;

&lt;p&gt;The inbound side was straightforward: Cloudflare already stamps &lt;code&gt;X-Forwarded-To&lt;/code&gt; and &lt;code&gt;X-Original-To&lt;/code&gt; on every forwarded message. I just needed to make sure those headers survived into my inbox intact.&lt;/p&gt;

&lt;p&gt;The outbound side was the real work. When you provide custom SMTP credentials to a mail client, the client hands off full control of the outgoing message. That's where envelope rewriting happens — inspect the message for routing context, determine the correct sender identity, rewrite the headers, and relay to the upstream MTA.&lt;/p&gt;

&lt;p&gt;A few things that made this interesting to get right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sender verification&lt;/strong&gt;: You can't let anyone claim any From address. The relay has to know which addresses are authorised for which accounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header precedence&lt;/strong&gt;: Mail clients sometimes set &lt;code&gt;Sender:&lt;/code&gt; and &lt;code&gt;Reply-To:&lt;/code&gt; in ways that conflict. Getting the priority chain right takes care.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bounce handling&lt;/strong&gt;: When a rewritten outbound message bounces, the bounce goes to &lt;code&gt;MAIL FROM&lt;/code&gt; — which is now your domain address. You need to route those back correctly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;After setting this up, the workflow became:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All domain email lands in one inbox&lt;/li&gt;
&lt;li&gt;Hit reply — correct sender, every time, automatically&lt;/li&gt;
&lt;li&gt;No manual address selection&lt;/li&gt;
&lt;li&gt;No per-seat mailbox costs&lt;/li&gt;
&lt;li&gt;No context switching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I called the tool &lt;strong&gt;OhRelay&lt;/strong&gt; and opened it up to early access: &lt;a href="https://ohrelay.com" rel="noopener noreferrer"&gt;ohrelay.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It works on top of Cloudflare Email Routing, so if you're already using that for inbound, setup is mostly just DNS and one SMTP config in your mail client. The guide covers Gmail, Outlook, and Apple Mail.&lt;/p&gt;




&lt;p&gt;If you've been living with the wrong-sender problem or managing too many mailbox seats, it might be worth a look. Happy to answer questions in the comments about how the relay layer works — it's an interesting corner of email infrastructure that doesn't get talked about much.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>selfhosted</category>
      <category>email</category>
      <category>cloudflare</category>
    </item>
  </channel>
</rss>
