next.js: `@next/font` does not work in custom `pages/_document`
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000
Binaries:
Node: 18.12.1
npm: 8.19.2
Yarn: 1.22.19
pnpm: N/A
Relevant packages:
next: 13.1.2-canary.8
eslint-config-next: 13.1.2
react: 18.2.0
react-dom: 18.2.0
warn - Latest canary version not detected, detected: “13.1.2-canary.8”, newest: “13.1.2”.
Please try the latest canary version (npm install next@canary
) to confirm the issue still exists before creating a new issue.
Read more - https://nextjs.org/docs/messages/opening-an-issue
Which area(s) of Next.js are affected? (leave empty if unsure)
Font optimization (@next/font)
Link to the code that reproduces this issue
WIP
To Reproduce
Define a font
Create a custom document at pages/_document.tsx
Import the fonts and apply the variables to the <Html>
Next element
Describe the Bug
Classes have no variable definition. When applied further down the dom (IE to a component or page) they do have a definition.
Expected Behavior
Classes would have a definition and apply CSS variables properly when applied to the root HTML element.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 5
- Comments: 16 (2 by maintainers)
I understand i don’t need to import it in layouts since app is rendered on every page. But I don’t want a wrapper around everything on every page just to add a font. So the alternative would be to apply it to some existing markup, which would only exist in our layouts. For now, I’ve gone with a CSS variable workaround like the following:
and then define the font family on the HTML element in globals.css
html { font-family: var(--font-sans); }
. I guess we’ll come up with a cleaner solution to this when the app folder is finalized and we can migrate over.@PeterKottas thanks for pointing out the dependence on
styled-jsx
I didn’t actually know what those attributes were doing. I removed that and it shaved about ~2kb, so not hugely significant but worth removing since we aren’t using it anywhere else. What I now am using:It is probably fine to apply the font family as you have there, I was just worried about specificity issues having that font family defined in style tag vs all of our other styles coming from stylesheets - I think you could do the same to remove the styled JSX usage with dangerouslySetInnerHTML.
@alex-pominov solution worked for me, but I had to add on className too
Google fonts does not seem to be working at all in app.
In our project we also had to set font variable at body level, to cover modal and popover styles that renders in portals. That’s what I using:
Try using
pages/_app.tsx
not/pages/_document.tsx
🙏🏼Learn more here: https://nextjs.org/docs/basic-features/font-optimization#google-fonts
don’t belive it’s supposed to
Good tip about the preload attribute! I totally missed that. Thanks. Now I am quite happy with the style approach. The only change I made compared to your version is I wrapped the style attribute with the next Head element. I don’t think it’s necessary these days, but I still think it’s best practice and it could theoretically prevent FOUT even further.