Next.js 在从 Google Fonts 下载字体时总是失败。

7

我第一次使用create-next-app创建了一个新的Next.js项目,并且成功运行了npm run dev

问题是,每次Next.js启动时都会显示:

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.

我的目标是让 Next.js 使用实际字体而不是备用字体。

我不知道为什么会发生这种情况,因为我还没有在 Next.js 中做出任何更改。即使在浏览器中打开 URL https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2 也可以正常工作,所以我猜这不是一个网络问题。

我尝试在 Next.js 的文档中进行搜索,但没有找到重复内容。

这是位于 src/app/ 内的 layout.tsx

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>
  )
}

此外,我正在运行的是 Node 版本 20.3.0 和 npm 版本 9.4.1,使用 Next.js 13.4。基本上是写这个问题时的最新版本。


它在我的端上工作,这是Next.js提供的演示。也许尝试不同的浏览器? - undefined
尝试清除缓存。还可以尝试使用VPN。可能是网络问题,因为在我的端上也能正常工作。 - undefined
@user16967562 我尝试了不同的浏览器,问题仍然存在。每次都使用备用字体。*.__className_f6fa1fbody元素*。 - undefined
@MoinulHaq 仍然清除缓存并使用不同浏览器无法解决问题。 - undefined
@kevin-m-mansour 这个错误代码是网络错误。有时候DNS可能会导致这样的问题,你可以尝试使用VPN来解决。先清除缓存,然后再试一下。 - undefined
@MoinulHaq 这不是缓存问题,请看我的回答。 - undefined
2个回答

18
尝试不同的浏览器和清除缓存也没有帮助。我通过添加键 display: 'swap'来解决了这个问题,其中值 swap的意思是:

给字体设置一个极短的块期和无限的交换期。

字体的"block"期指的是:

如果字体加载失败,任何试图使用该字体的元素必须渲染一个不可见的备用字体。如果字体在这个期间成功加载,它将正常使用。

而字体的"swap"期指的是:

如果字体加载失败,任何试图使用该字体的元素必须渲染一个备用字体。如果字体在这个期间成功加载,它将正常使用。

这基本上就是我要找的东西。
我还添加了键 adjustFontFallback: false,它的意思是:
一个布尔值,用于设置是否使用自动回退字体来减少累积布局位移。默认值为true
所以这是我的最终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>
  )
}

0
对我来说,在我安装了SSL的生产环境中,字体加载正确。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接