Skip to content

fix(next/font/local): omit font-weight descriptor when no weight is specified - #2843

Open
vjymisal0 wants to merge 1 commit into
cloudflare:mainfrom
vjymisal0:fix/webpack-loader-process-env
Open

fix(next/font/local): omit font-weight descriptor when no weight is specified#2843
vjymisal0 wants to merge 1 commit into
cloudflare:mainfrom
vjymisal0:fix/webpack-loader-process-env

Conversation

@vjymisal0

Copy link
Copy Markdown

Fixes #2793

Problem

The next/font/local shim's generated @font-face rule always defaulted to font-weight: 400 whenever neither the source nor the top-level options specified a weight:

const weight = sanitizeFontDescriptorValue(src.weight ?? options.weight ?? "400") ?? "400";

For variable fonts with a wght axis, this clamps the font face to the regular (400) instance. Elements styled with e.g. font-weight: 600 still compute to 600 in the CSSOM, but the browser renders the 400 instance of the variable font instead of interpolating to 600, because the @font-face rule pins the descriptor.

Fix

packages/vinext/src/shims/font-local.ts: only emit the font-weight descriptor when a weight was actually specified on the source or top-level options. font-style keeps its existing "normal" default, matching the expected output in the issue.

This matches Next.js, which only emits font-weight in the generated CSS when weight/defaultWeight is provided (see packages/font/src/local/loader.ts and the Turbopack next_font/local/stylesheet.rs implementation, both linked from the issue).

Test plan

  • Added two tests to tests/font-local-transform.test.ts:
    • omits the font-weight descriptor when no weight is specified (issue #2793) — asserts no font-weight in the generated CSS and that result.style.fontWeight is undefined when no weight is given.
    • still emits font-weight when a weight is specified on a single non-object source options — regression guard for the existing explicit-weight path.
  • Verified RED: reverted only the source fix (kept the new test) and confirmed the new test fails against the old code with font-weight: 400 present.
  • Verified GREEN: pnpm test tests/font-local-transform.test.ts — all 43 tests pass.
  • pnpm test tests/shims.test.ts -t "font" — all font-related tests in the broader shims suite pass (19 passed, rest unrelated/skipped).
  • vp check (format + lint + typecheck) passes on the changed files.

Scope note: this only touches font-local.ts — I checked font-google-base.ts for the same pattern and it doesn't hardcode a font-weight default, so it isn't affected.

…pecified

The generated @font-face rule always defaulted to `font-weight: 400`
when neither the source nor the top-level options specified a weight.
For variable fonts with a `wght` axis this clamps the font face to the
regular instance, so elements using e.g. font-weight: 600 no longer
render with the correct variable-font instance even though the
computed CSS font-weight value still matches.

Next.js only emits the font-weight descriptor when weight/defaultWeight
is provided (see packages/font/src/local/loader.ts and the Turbopack
next_font/local/stylesheet.rs implementation), so vinext should match
that and omit the descriptor entirely rather than inventing one.

Fixes cloudflare#2793
Copilot AI lite review requested due to automatic review settings August 9, 2026 05:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

next/font/local emits font-weight: 400 when weight is omitted, clamping variable fonts

2 participants