Skip to content

fix(router): production share links were dead (ingress strips /r) + host-scoped keys + copyable link URLs#43

Merged
keithfawcett merged 1 commit into
mainfrom
fix/router-prefix-stripping
Jul 9, 2026
Merged

fix(router): production share links were dead (ingress strips /r) + host-scoped keys + copyable link URLs#43
keithfawcett merged 1 commit into
mainfrom
fix/router-prefix-stripping

Conversation

@keithfawcett

Copy link
Copy Markdown
Contributor

Customer report (xispark): affiliate.xispark.com/r/<key> 404s. Investigation showed it's much bigger: the click router has been dead on every hosted domain — DO's ingress strips the matched /r prefix (exactly like /api), the router's routes expect the prefix, so every request fell through to Hono's default 404. Verified live on both the platform domain and the custom domain; the 404 body was Hono's default, not the router's own.

  • Router mounts both path shapes (prefixed for dev/self-host/direct, stripped for DO ingress)
  • Key-only lookups are host-scoped on white-label custom domains (Host → Tenant.customDomain → tenant-bound key query) — portal.brand.com/r/<key> resolves the right tenant and keys needn't be globally unique
  • Links page now renders full, copyable share URLs matched to context (platform: /r/<slug>/<key>; custom domain: /r/<key>; self-host keeps the relative display)

No spec/infra change needed — code accepts what the ingress actually sends. Suites green: api 192/192, portal 12/12, router 3/3.

🤖 Generated with Claude Code

…ere dead

DO App Platform's ingress strips the matched /r prefix before
forwarding (same as it strips /api), so in production the router
received /<key>, matched no route, and returned Hono's default 404 —
on EVERY hosted domain, platform and custom alike. The api component
survives identical stripping because its routes are mounted
prefix-less; the router's weren't.

- Mount both shapes: /r/:slug/:linkKey + /r/:linkKey (dev, self-host
  proxies, direct hits) and /:slug/:linkKey + /:linkKey (stripped).
  /health is static and Hono prefers static over params.
- Key-only lookups are now HOST-SCOPED on white-label custom domains
  (Host → Tenant.customDomain → tenant-bound Link query), so
  portal.brand.com/r/<key> resolves the right tenant's key and two
  tenants may share a key string. Unknown hosts keep the global
  single-tenant fallback.
- Links page: share keys render as full copyable URLs matched to the
  context — /r/<slug>/<key> on the platform origin, /r/<key> on a
  custom domain, relative display on self-host (portal origin isn't
  guaranteed to serve /r). /branding + usePublicBrand expose tenantSlug
  for the custom-domain detection.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@keithfawcett keithfawcett merged commit 5440ee3 into main Jul 9, 2026
9 checks passed
@keithfawcett keithfawcett deleted the fix/router-prefix-stripping branch July 9, 2026 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant