Search code examples
javascripttypescriptnext.jsgoogle-fonts

Next.js always fail at downloading fonts from Google Fonts


I've created a new Next.js project for the first time using create-next-app, and I've successfully run it with npm run dev.

The problem is that everytime Next.js starts, it says:

FetchError: request to https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2 failed, reason: 
    at ClientRequest.<anonymous> (C:\Users\user\Desktop\documents\node_modules\next\dist\compiled\node-fetch\index.js:1:65756)
    at ClientRequest.emit (node:events:511:28)
    at TLSSocket.socketErrorListener (node:_http_client:495:9)
    at TLSSocket.emit (node:events:511:28)
    at emitErrorNT (node:internal/streams/destroy:151:8)
    at emitErrorCloseNT (node:internal/streams/destroy:116:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  type: 'system',
  errno: 'ENETUNREACH',
  code: 'ENETUNREACH'
}
- error Failed to download `Inter` from Google Fonts. Using fallback font instead.

My goal is to make Next.js use the actual font not the fallback one.

I don't know why this happens as I didn't change anything in Next.js yet. Even opening the URL https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2 in my browser works well so I guess it's not a networking issue.

I tried to search in Next.js documentation and I didn't find any duplicates here.

Here's layout.tsx that's located inside src/app/:

import './globals.css'
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

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

Also, I'm running Node version 20.3.0 and npm version 9.4.1 with Next.js 13.4. Basically the latest at the time of writing this question.


Solution

  • Trying different browsers and clearing the cache didn't help either. I've solved it by adding key display: 'swap', where value swap means:

    Gives the font face an extremely small block period and an infinite swap period.

    Where font "block" period means:

    If the font face is not loaded, any element attempting to use it must render an invisible fallback font face. If the font face successfully loads during this period, it is used normally.

    And font "swap" period means:

    If the font face is not loaded, any element attempting to use it must render a fallback font face. If the font face successfully loads during this period, it is used normally.

    And that's pretty much what I was looking for.

    I've also added key adjustFontFallback: false which means:

    A boolean value that sets whether an automatic fallback font should be used to reduce Cumulative Layout Shift. The default is true.

    So here's my final layout.tsx:

    import './globals.css'
    import { Inter } from 'next/font/google'
    
    const inter = Inter({ subsets: ['latin'], display: 'swap', adjustFontFallback: false})
    
    
    export const metadata = {
      title: 'Create Next App',
      description: 'Generated by create next app',
    }
    
    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode
    }) {
      return (
        <html lang="en">
          <body className={inter.className}>{children}</body>
        </html>
      )
    }