Skip to content

Commit 1f144f0

Browse files
authored
Fix Turbopack local font font-family declaration (#85913)
This fixes #85912, as the logic of injecting the `font-family` property should be mirrored from the Webpack implementation.
1 parent 0baa1f7 commit 1f144f0

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

crates/next-core/src/next_font/local/stylesheet.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,17 @@ pub(super) async fn build_font_face_definitions(
6262
};
6363
let query_str = qstring::QString::from(serde_json::to_string(&query)?.as_str());
6464

65+
// Check if `font-family` is explicitly defined in `declarations`
66+
let has_custom_font_family = options.declarations.as_ref().is_some_and(|declarations| {
67+
declarations
68+
.iter()
69+
.any(|declaration| declaration.prop == "font-family")
70+
});
71+
6572
definitions.push_str(&formatdoc!(
6673
r#"
6774
@font-face {{
68-
{}
69-
font-family: '{}';
75+
{}{}
7076
src: url('@vercel/turbopack-next/internal/font/local/font?{}') format('{}');
7177
font-display: {};
7278
{}{}
@@ -79,20 +85,24 @@ pub(super) async fn build_font_face_definitions(
7985
.map(|declaration| format!("{}: {};", declaration.prop, declaration.value))
8086
.join("\n")
8187
),
82-
scoped_font_family,
88+
if has_custom_font_family {
89+
"".to_owned()
90+
} else {
91+
format!("\nfont-family: '{}';", scoped_font_family)
92+
},
8393
query_str,
8494
ext_to_format(&font.ext)?,
8595
options.display,
8696
&font
8797
.weight
8898
.as_ref()
8999
.or(options.default_weight.as_ref())
90-
.map_or_else(|| "".to_owned(), |w| format!("font-weight: {w};")),
100+
.map_or_else(|| "".to_owned(), |w| format!("\nfont-weight: {w};")),
91101
&font
92102
.style
93103
.as_ref()
94104
.or(options.default_style.as_ref())
95-
.map_or_else(|| "".to_owned(), |s| format!("font-style: {s};")),
105+
.map_or_else(|| "".to_owned(), |s| format!("\nfont-style: {s};")),
96106
));
97107
}
98108

test/e2e/next-font/app/pages/with-local-fonts.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ const myFont2 = localFont({
1313
preload: false,
1414
variable: '--my-font',
1515
})
16+
const myFont1Override = localFont({
17+
src: '../fonts/my-font.woff2',
18+
declarations: [
19+
{
20+
prop: 'font-family',
21+
value: 'foobar',
22+
},
23+
],
24+
})
1625

1726
const roboto = localFont({
1827
preload: false,
@@ -134,6 +143,9 @@ export default function WithFonts() {
134143
<div id="second-local-font" className={myFont2.className}>
135144
{JSON.stringify(myFont2)}
136145
</div>
146+
<div id="first-local-font-override" className={myFont1Override.className}>
147+
{JSON.stringify(myFont1Override)}
148+
</div>
137149
<div id="roboto-local-font" className={roboto.className}>
138150
{JSON.stringify(roboto)}
139151
</div>

test/e2e/next-font/index.test.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -650,20 +650,25 @@ describe('next/font', () => {
650650
// Get all stylesheets
651651
const stylesheets = await browser.eval(`
652652
Array.from(document.styleSheets)
653-
.map(sheet => {
653+
.flatMap(sheet => {
654654
try {
655655
return Array.from(sheet.cssRules || sheet.rules || [])
656656
.map(rule => rule.cssText)
657-
.join('\\n')
658657
} catch (e) {
659658
return ''
660659
}
661660
})
662-
.join('\\n')
663661
`)
664662

665663
// Check that the custom declaration is included in the CSS
666-
expect(stylesheets).toContain('ascent-override: 90%')
664+
expect(stylesheets).toContainEqual(
665+
expect.stringContaining('ascent-override: 90%;')
666+
)
667+
668+
// Check that the custom declaration is included in the CSS and overrides the default family
669+
expect(stylesheets).toContainEqual(
670+
expect.stringContaining('font-family: foobar;')
671+
)
667672
})
668673
})
669674
})

0 commit comments

Comments
 (0)