nextjs - ✅(Solved) Fix Wrong behavior of local font's `font-family` handling in Turbopack [2 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#85912Fetched 2026-04-08 02:13:26
View on GitHub
Comments
2
Participants
2
Timeline
15
Reactions
0
Author
Timeline (top)
referenced ×4closed ×2commented ×2labeled ×2

Fix Action

Fixed

PR fix notes

PR #85913: Fix Turbopack local font font-family declaration

Description (problem / solution / changelog)

This fixes #85912, as the logic of injecting the font-family property should be mirrored from the Webpack implementation.

Missing feature from https://github.com/vercel/next.js/pull/85051

Changed files

  • crates/next-core/src/next_font/local/stylesheet.rs (modified, +15/-5)
  • test/e2e/next-font/app/pages/with-local-fonts.js (modified, +12/-0)
  • test/e2e/next-font/index.test.ts (modified, +9/-4)

Code Example

import localFont from 'next/font/local'

const geist = localFont({
  src: './geist.woff2',
  declarations: [
    {
      prop: 'font-family',
      value: "Geist",
    },
  ],
})
RAW_BUFFERClick to expand / collapse

The logic to allow specifying custom font-family of a local font implemented in #76274 is for Webpack only, and not ported to Turbopack.

Webpack

font-family: variableName is only inserted when there's no custom font family set:

https://github.com/vercel/next.js/blob/db5528317e24e0316e0497716976a715a325ca09/packages/font/src/local/loader.ts#L67

Turbopack

scoped_font_family is always inserted:

https://github.com/vercel/next.js/blob/db5528317e24e0316e0497716976a715a325ca09/crates/next-core/src/next_font/local/stylesheet.rs#L67-L82

Reproduction

import localFont from 'next/font/local'

const geist = localFont({
  src: './geist.woff2',
  declarations: [
    {
      prop: 'font-family',
      value: "Geist",
    },
  ],
})

With Turbopack, the above code results in a @font-face with two font-family properties:

<img width="1196" height="290" alt="Image" src="https://github.com/user-attachments/assets/d845ba1c-f126-47f4-bf11-f664d41b463d" />

extent analysis

TL;DR

To fix the issue, modify the Turbopack implementation to conditionally insert the scoped_font_family based on the presence of a custom font family.

Guidance

  • Review the Turbopack code in next-core/src/next_font/local/stylesheet.rs to understand why scoped_font_family is always inserted.
  • Compare the Webpack implementation in next.js/packages/font/src/local/loader.ts to see how it handles custom font families.
  • Consider modifying the Turbopack code to mimic the Webpack behavior, only inserting scoped_font_family when no custom font family is set.
  • Test the modified Turbopack implementation with the provided reproduction code to verify the fix.

Example

No code example is provided as the fix requires modifying the Turbopack implementation, which is written in Rust.

Notes

The issue is specific to Turbopack and requires changes to its implementation. The provided reproduction code and Webpack implementation can serve as a reference for the fix.

Recommendation

Apply workaround: Modify the Turbopack implementation to conditionally insert the scoped_font_family based on the presence of a custom font family. This will ensure consistent behavior with Webpack and fix the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING