mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[GH-ISSUE #885] next/font/google shim hardcodes :wght@100..900 when no weight is specified, causing HTTP 400 from Google Fonts for fonts with a narrower weight range #198
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#198
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @eashish93 on GitHub (Apr 24, 2026).
Original GitHub issue: https://github.com/cloudflare/vinext/issues/885
Summary
When a caller uses
next/font/googlewithout passing an explicitweightoption, the vinext shim builds the Google Fonts URL with:wght@100..900. Many Google Fonts don't support that full range (e.g. Sen is 400–800), so Google Fonts CDN responds with HTTP 400 and the stylesheet never loads. The rendered page computesfont-family: 'Sen', sans-serifcorrectly, but because no@font-faceregisters, the browser paints the genericsans-seriffallback — so the bug looks like "font-family cascade issue" even though the real fault is the URL.Reproduction
app/layout.tsx:curl -Ithat URL:Root cause
dist/shims/font-google-base.js:80-95:The hardcoded
:wght@100..900assumes every Google font is a 100–900 variable axis. Many aren't:Next.js real implementation looks up each family's axis metadata from a bundled fonts database and either fetches with no
:wght@(which makes Google serve the default variable font) or with the exact valid range. vinext's shim can't do the former because it always appends a:wght@segment.Suggested fix
The minimal, safe fix is to omit
:wght@…when noweightis provided. Google Fonts CDN handles the no-weight case correctly and returns the variable font (or the default weight for static fonts):A more Next.js-faithful fix would be to bundle a slimmed-down axis database (hexere already has a similar
google-fonts-meta.jsonfor its own use, ~500 KB at most) and either (a) validate the requested weight range against the font's real axis, or (b) auto-select a full range when the caller passes no weight.Impact
Every call site that uses
next/font/googlewithout an explicitweightoption and happens to pick a font whose axis range isn't exactly 100–900 silently loads nothing. The failure mode is invisible indocument.fonts(entries are registered by<link>-sourced@font-face, and a 400-response stylesheet registers no faces), which makes this bug very hard to diagnose — devs typically spend hours staring at Tailwind preflight cascade rules before checking the CDN response.Related: this is one of three shim-level issues I hit while porting a Next.js app to vinext — see also:
Workaround
Pass explicit weights that match the font's real axis range, e.g.: