next.js: [NEXT-1192] Failed to find font override - next/font/google

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 22.3.0: Mon Jan 30 20:38:37 PST 2023; root:xnu-8792.81.3~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.14.0
      npm: 9.3.1
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.2.5-canary.3
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0

Which area(s) of Next.js are affected? (leave empty if unsure)

Font optimization (@next/font)

Link to the code that reproduces this issue

https://github.com/maxencerb/next-font-bug

To Reproduce

// utils/fonts.ts
import { Unbounded } from 'next/font/google';

export const unbounded = Unbounded({
  subsets: ['latin'],
  display: 'swap',
})
// app/page.tsx
import { unbounded } from "../utils/fonts"

export default function Home() {
  return (
    <h1 className={unbounded.className}>TEST TITLE</h1>
  )
}

Describe the Bug

Output

Output works as expected

image

Console Output

error - Failed to find font override values for font `Unbounded`

Explaination

All fallback font metrics from google are loaded from next/font/google/get-fallback-font-override-metrics.ts where we can see the following method and doc :

// @ts-ignore
import { calculateSizeAdjustValues } from 'next/dist/server/font-utils'
// @ts-ignore
import * as Log from 'next/dist/build/output/log'

/**
 * Get precalculated fallback font metrics for the Google Fonts family.
 *
 * TODO:
 * We might want to calculate these values with fontkit instead (like in next/font/local).
 * That way we don't have to update the precalculated values every time a new font is added to Google Fonts.
 */
export function getFallbackFontOverrideMetrics(fontFamily: string) {
  try {
    const { ascent, descent, lineGap, fallbackFont, sizeAdjust } =
      calculateSizeAdjustValues(
        require('next/dist/server/google-font-metrics.json')[fontFamily]
      )
    return {
      fallbackFont,
      ascentOverride: `${ascent}%`,
      descentOverride: `${descent}%`,
      lineGapOverride: `${lineGap}%`,
      sizeAdjust: `${sizeAdjust}%`,
    }
  } catch {
    Log.error(`Failed to find font override values for font \`${fontFamily}\``)
  }
}

So I think there might be a fix but I don’t really know how to implement it. I tried looking at the local font optimization code.

Maybe someone can either find the solution to calculate the values with fontkit or at least update the json file under next/src/server/google-font-metrics.json and tell how to find those values.

Expected Behavior

Find the font fallback for any google font

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

NEXT-1192

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 47
  • Comments: 80 (11 by maintainers)

Commits related to this issue

Most upvoted comments

+1 for Instrument_Sans

Hi everybody! Adding " display: ‘swap’ " in options, helped me!

Hey, I started debugging it locally, here is what I found.

In my case I’m having issue with Bodoni Moda.

Error I’m having is the same as other issue participants had:

- error Failed to find font override values for font `Bodoni Moda`

I added a new log to display the exact error that happens by modifying and adding below lines of code in getFallbackFontOverrideMetrics function inside node_modules/next/dist/compiled/@next/font/dist/google/get-fallback-font-override-metrics.js:

    catch (err) {
        Log.error(`Failed to find font override values for font \`${fontFamily}\``);
        Log.error(err)
    }

Here is the error message

- error TypeError: Cannot destructure property 'category' of 'fontMetrics' as it is undefined.
    at calculateSizeAdjustValues (/node_modules/next/dist/server/font-utils.js:166:11)
    at getFallbackFontOverrideMetrics (/node_modules/next/dist/compiled/@next/font/dist/google/get-fallback-font-override-metrics.js:40:115)

So I went into calculateSizeAdjustValues function inside node_modules/next/dist/server/font-utils.js and it was rather clear that’s the line causing the issue:

    const fontMetrics = capsizeFontsMetrics[fontKey];

For some reason this file node_modules/next/dist/server/capsize-font-metrics.json does not contain information about this particular font. So I went into it and checked - here is my font object, sitting in this json file:

  "bodoniModa11pt": {
   "familyName": "Bodoni Moda 11pt",
   "category": "serif",
   "capHeight": 1500,
   "ascent": 2250,
   "descent": -800,
   "lineGap": 0,
   "unitsPerEm": 2000,
   "xHeight": 920,
   "xWidthAvg": 920
 },

Looks like it should be found?

I decided to debug what fonKey is by adding

console.log({fontName, fontKey})

to previously mentioned calculateSizeAdjustValues function, here is the result:

{ fontName: 'Bodoni Moda', fontKey: 'bodoniModa' }

Looks like the issue is with fontKey value. I guess there are multiple possibilities why it doesn’t work

  • fontKey is not properly computed and doesn’t include 11pt
  • object held inside capsize-font-metrics.json file is not named correctly
  • bodoniModa11pt is not the same as bodoniModa and it should has its own entry

In Google Font I see this font is named Bodoni Moda without 11pt suffix. Maybe it’s just a leftover from some old implementation and changing it to bodoniModa is enough of a fix?

Adding @font-face on my css fixed it for me:

@font-face {
  font-family: 'Bungee Spice';
  src: url('/fonts/BungeeSpice-Regular.woff2') format('woff2');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

Kinda solved for me with display: 'swap' and adjustFontFallback: false properties:

⨯ Failed to find font override values for font `Yuji Hentaigana Akari` : Code

import { Akaya_Telivigala, Yuji_Hentaigana_Akari, Lusitana } from 'next/font/google'

export const akaya = Akaya_Telivigala({
    weight:'400',
    subsets: ['latin']
});
export const yuji = Yuji_Hentaigana_Akari({
    weight:'400',
    subsets: ['latin']
});
export const lusitana = Lusitana({
    weight:['400', '700'],
    subsets: ['latin']
});

Solution Code

import { Akaya_Telivigala, Yuji_Hentaigana_Akari, Lusitana } from 'next/font/google'

export const akaya = Akaya_Telivigala({
    weight:'400',
    subsets: ['latin']
});
export const yuji = Yuji_Hentaigana_Akari({
    weight:'400',
    subsets: ['latin'],
    display: 'swap',
    adjustFontFallback: false
});
export const lusitana = Lusitana({
    weight:['400', '700'],
    subsets: ['latin']
});

Thought sometimes the font fails to load, well my theory is that the problem is within the size of some fonts that can’t fit to Font fallback adjustment, this solution could work for small things but I can’t recommend it to any real proyect, its better to ignore the fail massage if the font is loading allright

Having the same issue with Golos_Text

Thanks for the shout @shaun-scale! We’ll take a look 🙏

cc @leerob - lots of struggle here

Same issue with Newsreader

Same issue for Geologica font 🙏

Same issue with Bricolage_Grotesque, resolved with the following:

export const secondaryFont = Bricolage_Grotesque({
  subsets: ["latin"],
  variable: "--font-grotesque",
  display: "swap",
  adjustFontFallback: false,
});

Same with Onest font. Is there a permanent fix for this without resorting to display:swap?

I don’t know if it works on other devices or not. But in my personal project it works.

TL;DR

Use a custom variable when declaring a NextFont component, then apply it as className in <head>. After that call custom variable in global.css file using font-family. For further documentation please refer to Font Optimization.

Example :

// @/app/layout.tsx

import { Sono } from "next/font/google";

const sono = Sono({
  subsets: ["latin"],
  variable: '--custom-font-sono'
});

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={ `${sono.variable}` }>
      <body>
        {children}
      </body>
    </html>
  );
}

/* @/style/globals.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  font-family: var(--custom-font-sono);
}

ERROR CODE

To Reproduce

This is my code when there is an error.

// @/app/layout.tsx

import Header from "@/components/Header";
import { Kumbh_Sans, Sono } from "next/font/google";

const kumbhsans = Kumbh_Sans({
  weight: "400",
  subsets: ["latin"]
});

const sono = Sono({
  subsets: ["latin"]
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className={ kumbhsans.className }>
        <Header className={ sono.className }/>
        {children}
      </body>
    </html>
  );
}

// @/components/Header.tsx

export default function Header({ fontClass }: { fontClass: string }) {
  return (
    <header>
      <h1 className={ fontClass }>example</h1>
    </header>
  );
}

Display Output

Output works as expected.

{7E711288-F041-4134-9D33-915366583ED5} png

Console Output

error - Failed to find font override values for font `Sono`

I don’t know why only one font is error.

BRAINSTORMING

Clue

Based on @BMscis comment on May 7th https://github.com/vercel/next.js/issues/47115#issuecomment-1537258403 .

Idea

I was thinking what if the NextFont component is converted back in CSS and calls the font in CSS format.

Solution

Then I found the answer in the Font Optimization documentation.

SOLVED CODE

To Reproduce

This is my code when I tried the idea.

// @/app/layout.tsx

import Header from "@/components/Header";
import { Kumbh_Sans, Sono } from "next/font/google";

const kumbhsans = Kumbh_Sans({
  weight: "400",
  subsets: ["latin"],
  variable: '--custom-font-kumbhsans'
});

const sono = Sono({
  subsets: ["latin"],
  variable: '--custom-font-sono'
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" className={ `${kumbhsans.variable} ${sono.variable}` }>
      <body>
        <Header />
        {children}
      </body>
    </html>
  );
}

// @/components/Header.tsx

export default function Header() {
  return (
    <header>
      <h1>example</h1>
    </header>
  );
}

/* @/style/globals.css */

@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  font-family: var(--custom-font-kumbhsans);
}

h1 {
  font-family: var(--custom-font-sono);
}

Display Output

Output works as expected.

{7E711288-F041-4134-9D33-915366583ED5} png

same issue with Inter_Tight

Same for Instrument Sans

Same issue with Onest, resolved with the following:

export const onest = Onest({
  adjustFontFallback: false,
  display: 'swap',
  subsets: ['latin'],
});

next/font error: Unknown font Wix Madefor Display

@mwawrusch It is on <picture data-single-emoji=":nextjs:" title=":nextjs:">:nextjs:</picture> v14.3.0-canary.4 now!

Hi everyone! This fix is on the latest canary now (v14.1.1-canary.66).

Let us know if you are no longer seeing the font override error!

FYI I’m pretty sure you don’t need display: 'swap'; you just need adjustFontFallback: false. This happened to me for a font, and I have display: 'block'; simply setting adjustFontFallback: false resolved it, and I didn’t need to set it to swap. (Personally, I aesthetically prefer the text to be invisible during the block period instead of being rendered in a different font; I find the visual shift, if there is one, to be less jarring when the layout goes from invisible-text-with-slightly-wrong-layout to correct instead of visible-text-in-the-wrong-font-and-the-wrong-layout to correct.)

It looks like the underlying issue is that the default for adjustFontFallback is true, and that triggers the getFallbackFontOverrideMetrics function to be called, which eventually gets the calculateSizeAdjustValues function to look up the font in a precomputed JSON hash called capsize-font-metrics.json, which is pulled in a task from the @capsizecss/metrics/entireMetricsCollection package. If the Google font isn’t in that precomputed metrics collection at the version number that your version of NextJS is using — the latest version of NextJS is using @capsizecss/metrics v1.1.0, which is about a year old — it seems like the fallback font override will probably break.

I also noticed that the getFallbackFontOverrideMetrics function has a pretty telling comment:

/*
 * TODO:
 * We might want to calculate these values with fontkit instead (like in next/font/local).
 * That way we don't have to update the precalculated values every time a new font is added to Google Fonts.
 */

Which seems like a prescient note! 😆

Kinda solved for me with display: 'swap' and adjustFontFallback: false properties:

@joparedesm This saved my day!! Thank you so much!

@samcx

Pull request should be merged soon: https://github.com/seek-oss/capsize/pull/192 . Appreciate all your work.

@samcx , here is a small repro for this issue in Next.js 14.1.2, but what I missed yesterday was that Next.js 14.1.2 release notes say that this release does not include all pending features/changes on canary.

Note: this is a backport release for critical bug fixes – this does not include all pending features/changes on canary

   ▲ Next.js 14.1.2
   - Experiments (use at your own risk):
     · typedRoutes

   Creating an optimized production build ...
 ⨯ Failed to find font override values for font `Young Serif`

New Update!

This behaviour is random and happens unexpectedly. It doesn’t seem like I have it right now! I didn’t made any change to the code.

https://github.com/vercel/next.js/assets/72091386/de5ec62c-6587-49b1-8e11-b272ffef182d

I can confirm this issue still persists and is there a new fix WIP?

I would be super happy to work on this issue if no one’s currently working on one 😃

May be unhelpful but I just update the import to next/font/google (which I know you’ve already done) and restarted the dev server and it seemed to work again.

@samcx M_PLUS_Rounded_1c don’t work if weight is 900

+1 for Instrument_Sans

any solutions ?

In the end I have downloaded the font and am using it as I used to do…

image Problem is still not fixed with the Gabarito google font. It doesn’t give me an error but my font is still system-ui. I’m using next@14.2.0-canary.47 (also tried 14.1.1 and 14.1.4)

image

Hi everyone! This fix is on the latest canary now (v14.1.1-canary.66).

Let us know if you are no longer seeing the font override error!

Seems like it’s now solved! Thanks👍

+1 for REM fonts

Same for Playfair

same issue for “Instrument Sans” font.

fonts-issue

Any updates on this? Having the same issue with Nanum Pen Script

Any update or expected timeline?

Another thing, I’m seeing that a lot of people including myself are having issues with Next new appdir in the different steps of developing an app. I would recommend that u don’t use the app dir and use the common pages structure, I’m using v 13.4.1 that it’s supposed to be stable and I’m breaking my head against the keyboad bc I can’t get a font or a simple animation to work.

I’ve also been bashing my ahead against my keyboard, it’s a real struggle after using the old system for so long 😅. Take this with a grain of salt as I’ve been very optimistic (and enthusiastic!) about this change for a while now, but:

/app is a massive shift in the Next paradigm and many other components in the ecosystem haven’t quite adapted to the new format. In my opinion, the App directory is a lot faster and is just so much more convenient to use! Personally, I make a lot of apps that pull data from APIs or databases, and the appDir just makes my life easier. Change usually takes a while, esp with smth as big as this, so it might take a while for third-party components and modules to become compatible with the new system.

In the mean time, you could wrap client-designed/legacy components in client component wrappers to have them work with the new system - I think the Next docs even talk about doing this (although I may be wrong).

Also, still having this issue with Golos_Text as of today on 13.4.4 (appdir). Hopefully this can be addressed soon 😄

Same with Texturina

Another thing, I’m seeing that a lot of people including myself are having issues with Next new appdir in the different steps of developing an app. I would recommend that u don’t use the app dir and use the common pages structure, I’m using v 13.4.1 that it’s supposed to be stable and I’m breaking my head against the keyboad bc I can’t get a font or a simple animation to work.

Having the same issue with Golos_Text

Me too.

Seem to be having the same issue with Alkatra