The frontend-prod image ships no web fonts: every .woff2 404s into index.html #891

Closed
opened 2026-09-27 07:47:54 +00:00 by claude-bot · 0 comments
Collaborator

This came out of lane 8 P1's render check (#888).

What happens

In the frontend-prod image built from the repo's Dockerfile, no .woff2 file ends up in dist/. Running find dist -iname '*.woff2' inside the builder stage returns nothing.

The built CSS still has its @font-face rules, for example url(./files/figtree-latin-wght-normal.woff2) from @fontsource-variable/*. So in the browser:

  • every font request (GET /assets/files/figtree-latin-wght-normal.woff2) gets 200 text/html, because nginx's SPA fallback serves index.html;
  • the browser logs OTS parsing error: invalid sfntVersion;
  • the whole app renders in the fallback sans-serif.

The .woff2 sources are present in node_modules/@fontsource-variable/*/files/.

Evidence

From the e2e stack (a frontend-prod image), This week, Storyline and the wiki all render in the fallback font. See the render shots in #888's check.

Likely scope

Every environment built from frontend-prod, which includes dev and prod. The display font (--display) and the body sans have probably been missing since lane 0 (#739–#741) moved to @fontsource-variable.

To do

  1. Find out why Vite/Rollup doesn't emit the fontsource CSS @imports' font files in the production build. Check the @import path style, build.assetsInlineLimit, base, and whether the CSS is imported through a path Vite treats as external.
  2. Fix it, and add a build-level check: fail the frontend build, or a CI step, if dist/ has an @font-face url() that doesn't resolve to a file in dist/.
  3. Make nginx return a real 404 for missing /assets/*, instead of the SPA fallback, so missing assets fail loudly. Check that this doesn't break client routes.
  4. Verify in a real frontend-prod image: the fonts load with content-type: font/woff2, and there's no OTS error.
This came out of lane 8 P1's render check (#888). ## What happens In the `frontend-prod` image built from the repo's `Dockerfile`, **no `.woff2` file ends up in `dist/`.** Running `find dist -iname '*.woff2'` inside the builder stage returns nothing. The built CSS still has its `@font-face` rules, for example `url(./files/figtree-latin-wght-normal.woff2)` from `@fontsource-variable/*`. So in the browser: - every font request (`GET /assets/files/figtree-latin-wght-normal.woff2`) gets **200 `text/html`**, because nginx's SPA fallback serves `index.html`; - the browser logs `OTS parsing error: invalid sfntVersion`; - the whole app renders in the fallback sans-serif. The `.woff2` sources are present in `node_modules/@fontsource-variable/*/files/`. ## Evidence From the e2e stack (a frontend-prod image), This week, Storyline and the wiki all render in the fallback font. See the render shots in #888's check. ## Likely scope Every environment built from `frontend-prod`, **which includes dev and prod.** The display font (`--display`) and the body sans have probably been missing since lane 0 (#739–#741) moved to `@fontsource-variable`. ## To do 1. Find out why Vite/Rollup doesn't emit the fontsource CSS `@import`s' font files in the production build. Check the `@import` path style, `build.assetsInlineLimit`, `base`, and whether the CSS is imported through a path Vite treats as external. 2. Fix it, and add a **build-level check**: fail the frontend build, or a CI step, if `dist/` has an `@font-face` `url()` that doesn't resolve to a file in `dist/`. 3. Make nginx return a real 404 for missing `/assets/*`, instead of the SPA fallback, so missing assets fail loudly. Check that this doesn't break client routes. 4. Verify in a real frontend-prod image: the fonts load with `content-type: font/woff2`, and there's no OTS error.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#891
No description provided.