This page was translated from the original by AI.

In the previous post, I described how I used Claude Code to help migrate Astro to EmDash. The deployment went smoothly, but the cliffhanger at the end was a real crisis: after binding a custom domain, my Passkey login stopped working, and the admin panel reported no email service configured. This post is a full account of that escape and the authentication fixes.

Why Was I Locked Out?

After pointing my custom domain at the Cloudflare Worker, I happily opened https://epona.me/_emdash/admin to log in, only to find that no Passkey verification prompt appeared.

A moment of reflection made it clear: this is WebAuthn's security design at work. Passkey credentials are strictly bound to the access domain (Origin / Relying Party ID). The ones I'd created under *.workers.dev 临时域名下注册的凭据,在epona.me simply couldn't work on the new domain.

At that point the system suggested logging in via email, but here's the awkward part: I'd just deployed and hadn't configured any email service. Fortunately, I could still use *.workers.dev/_emdash/admin to get into the admin panel.

Configuring Email Service for EmDash

Since I was already in the admin panel, the priority was to get email configured quickly so I wouldn't get locked out again.

Choosing a Plugin

Going into the admin panel's Settings → Email, the interface showed: No email provider configured. This kind of configuration was obviously something to hand over to Claude Code.

image-1788779054099.png

After some exploration, Claude Code offered three options:

  1. Cloudflare Email Sending: natively supported, sending email directly from the Cloudflare edge.
  2. Resend: a third-party plugin officially recommended by EmDash.
  3. Postmark / AWS SES and other traditional SMTP/API services.

Given that the entire blog stack runs on the Cloudflare ecosystem (Workers + D1 + R2), I preferred to minimize external dependencies, so I went with Cloudflare Email Sending.

Note: this feature requires the Cloudflare Workers paid plan ($5/month). Since the price is reasonable and I'd likely need other advanced features later, I took the opportunity to upgrade.

Plugin Installation and Testing

Guided by Claude Code, we installed and enabled the email plugin for EmDash. After deployment, a new Cloudflare Email entry appeared in the left menu of the admin panel. After configuring the sender address, I entered my personal email in the test box and hit send—the test email arrived without a hitch!

Screenshot 2026-09-08 at 20.06.58.png

The siteUrl Problem

With email working, I logged out of workers.dev and went to the custom domain https://epona.me/_emdash/admin to try email login. The email did send this time, but here's the weird part: the magic link in the email still pointed to *.workers.dev! Since the login token doesn't strictly validate the origin domain, I had to manually copy the link, replace the leading domain with my own epona.me, and force my way in.

Next, I had the AI investigate why Passkey still couldn't be added on the custom domain. The AI's analysis pinpointed the key issue: EmDash's core configuration was missing an explicit definition of the base site URL (siteUrl)! Without it, EmDash's internal absolute link generation and the RP ID that WebAuthn relies on both fall back to the Worker's original temporary domain. So we added this to the project config file:

emdash({
    siteUrl: "https://epona.me",
    // ... 其他配置
})

After rebuilding and redeploying, the magic link was correct, and Passkey could finally be bound to the custom domain.

Summary

Looking back at this login authentication configuration that nearly went sideways, there are two lessons worth sharing:

  1. Configuration Order: Set the Domain First, Then Authentication

When deploying a full-stack CMS on Cloudflare Workers, the first step should be to hardcode the custom domain's siteUrl in the config file and bind the domain. Don't take the shortcut of configuring all your accounts and credentials under the temporary domain.

  1. Multiple Login Redundancy Is a Must

Modern web passwordless (Passkey) login is a great experience, but because it's physically bound to the Origin, it has low fault tolerance. Before going live, make sure email service is set up as a fallback—otherwise, any change to your domain or credentials can easily lock you out completely.

Epona
Written byEpona

There's nothing wrong with having a little fun

x.com/simura_epona

Loading comments…