Skip to content

an app cannot serve a static file — which makes the framework's own self-host-your-fonts posture unsatisfiable #446

Description

@ivndev001

What

There is no app-writable route for an arbitrary static file. x dev's route table is a closed literal — apiRoutes, assetRoutes, storageRoutes, islandRoutes, styleRoutes, appRoutes (packages/cli/src/cmd-dev.ts:209-219) — with no app-supplied slot.

GET /icon.png     -> 404      # apps/web/site/icon.png IS committed
GET /favicon.ico  -> 200      # dedicated framework route

(measured against a running 20.1.0 app)

Why it matters beyond one app: the guard-rails point at a door that is not there

Together those say, correctly: self-host your fonts. But nothing can then serve a self-hosted font.

Escape hatches ruled out at source

  • runtime.ts middleware wraps a route that already matched; an unmatched path throws routeNotFound first (packages/http/src/stages.ts:173).
  • An action cannot return a Response — json(result) or redirect(...) only.
  • /media is gated on storage:read; /icons serves only the PWA matrix.
  • RouteMeta has no link field, so there is no <link rel="preload"> seam either.

The workaround we shipped (so you can judge how bad the gap is)

Both fonts base64-embedded as data: URIs inside the app stylesheet — the one app file the framework does serve — plus security.csp.extend: { 'font-src': ['data:'] }. It works (verified in Chrome: both faces loaded, no CSP errors) at the cost of +33% bytes, no independent caching, and no preload.

Suggested shapes, least invasive first

  1. A declared static directory per surface that joins the route table the way styleRoutes does.
  2. An app-supplied route slot.
  3. A fontFace seam on defineTheme() that emits the @font-face and the asset route together — which keeps the existing validator honest instead of worked around.

Found while rebuilding a small app (ivndev001/dz-showcase, private) on Ultimate 20.1.0; re-checked against main at 46aa5b9 (20.1.2) on 2026-09-17 before filing. Filed by an agent on the repository owner's instruction.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions