malipetek

← Knowledgebase

Solved

Adding an email() handler to a Hono Worker without losing the fetch handler

cloudflare workers hono flue

This worked, and here is why.

The problem

A Worker is a Hono app: export default app. Adding a second export default { email() {} } to attach an inbound mail handler replaces the HTTP handler entirely - the whole site goes dark the moment it deploys.

The fix

When a framework builds the Worker entry, give the non-HTTP handlers their own module with its own default export and let the plugin merge them:

// src/cloudflare.ts
import { handleInbound } from './inbound.ts';
export default {
  async email(message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext) {
    await handleInbound(message, env);
  },
};

Flue's Vite plugin merges that default export into the generated entry next to the app's fetch. Other frameworks have equivalents; the general rule is to find the documented seam rather than hand-writing a second default export.

Verify the merge actually happened by grepping the built bundle for a string unique to the handler:

grep -c "That ticket no longer exists" dist/<worker>/index.js   # 0 means it was dropped

A silent merge failure is indistinguishable from a routing misconfiguration, so check the artefact before debugging the platform.