In my project raam I'm tying set "Inter" as my font by linking to a stylesheet from Google Fonts.
In Head (a component that extends next/head) I'm using:
<link rel="preconnect" href="https://fonts.gstatic.com/" crossOrigin="" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
rel="stylesheet"
/>
(note the preconnect to the actual font assets, then the display=swap which is intended to show the fallback font until the loaded font is swapped in)
When I then go to view the page (in Firefox particularly) I see a flash of unstyled/invisible text:
https://raam-git-chore-inter.joebell.now.sh/

Steps to reproduce the behavior, please provide code snippets or a repository:
The system font is seen first, and 'swapped' to Inter on load.
I appreciate there's a lot of variables here: Theme UI, Google Fonts, Now.sh, Next.js, but it would be good if we can figure out the root cause here for others using Next.js. If it's something that could be resolved by adding some documentation I'd be more than happy to do so.
Thanks again for all of the team's hard work on Next.js, it's a real pleasure to work with
Did some testing on other devices: iPad OS and iOS have no issues. Seems like it only occurs on macOS but I can鈥檛 verify Windows. I've tried removing the Theme UI hook to see if this was the root, but it appears to make no difference.
As an update I've tested this new approach, which is a mix of font-loading performance suggestions I've found online:
<link
rel="preload"
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
as="style"
/>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
rel="stylesheet"
media="print"
// // Next.js doesn't like this but it allows us to load CSS asynchronously
// @ts-ignore
onLoad="this.media='all'"
/>
| Before | After |
|--------|-------|
|
|
|
However a slight flash still remains and TypeScript doesn't like my onLoad="this.media='all'" as it doesn't accept string values. Am I doing this wrong or do I need to raise a PR to update types?
I have a hunch that something in next/head is changing after load on the client, but I'm not experienced enough to know what's happening under the hood to cause this FOUT.
Update #1 - I've tried fg-loadCSS but the same FOUT issue occurs. Whatever approach there is still a small FOUT.
After some further investigation with @csswizardry, we found that when JS is disabled the onload attribute is missing entirely:

What's even stranger is once JS is enabled, this behaves as expected but moves further down the <head> element:

This leads me to think next/head is rendering without onLoad on the server, then shuffling around things upon hydration
This leads me to think next/head is rendering without onLoad on the server, then shuffling around things upon hydration
onload is handled by React so I assume it's read as if it's a React event handler.
Thanks for getting back to me @timneutkens, I was just about to update this issue as I've managed to build a workaround solution in the meantime: next-google-fonts
I'd still prefer to use onload, but it seems fine for now
Most helpful comment
As an update I've tested this new approach, which is a mix of font-loading performance suggestions I've found online:
| Before | After |
|
|
|--------|-------|
|
However a slight flash still remains and TypeScript doesn't like my
onLoad="this.media='all'"as it doesn't accept string values. Am I doing this wrong or do I need to raise a PR to update types?I have a hunch that something in
next/headis changing after load on the client, but I'm not experienced enough to know what's happening under the hood to cause this FOUT.Update #1 - I've tried
fg-loadCSSbut the same FOUT issue occurs. Whatever approach there is still a small FOUT.