跳到内容

字体优化

next/font 将自动优化你的字体(包括自定义字体),并移除外部网络请求,以提升隐私和性能。

🎥 观看: 了解更多关于使用 next/font 的信息 → YouTube (6 分钟)

next/font 包含 内置的自动自托管 功能,适用于任何字体文件。这意味着你可以最佳地加载 Web 字体,零布局偏移,这要归功于底层使用的 CSS size-adjust 属性。

这个新的字体系统还允许你方便地使用所有 Google 字体,同时兼顾性能和隐私。CSS 和字体文件在构建时下载,并与其余静态资源一起自托管。浏览器不会向 Google 发送任何请求。

Google 字体

自动自托管任何 Google 字体。字体包含在部署中,并从与你的部署相同的域名提供服务。浏览器不会向 Google 发送任何请求。

首先,从 next/font/google 导入你想要使用的字体作为一个函数。我们建议使用 可变字体 以获得最佳性能和灵活性。

要在所有页面中使用字体,请将其添加到 /pages 下的 _app.js 文件,如下所示

pages/_app.js
import { Inter } from 'next/font/google'
 
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({ subsets: ['latin'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}

如果你不能使用可变字体,你将需要指定字重

pages/_app.js
import { Roboto } from 'next/font/google'
 
const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={roboto.className}>
      <Component {...pageProps} />
    </main>
  )
}

你可以通过使用数组来指定多个字重和/或样式

app/layout.js
const roboto = Roboto({
  weight: ['400', '700'],
  style: ['normal', 'italic'],
  subsets: ['latin'],
  display: 'swap',
})

须知:对于包含多个单词的字体名称,请使用下划线 (_)。例如,Roboto Mono 应导入为 Roboto_Mono

<head> 中应用字体

你也可以在不使用包装器和 className 的情况下使用字体,方法是将其注入到 <head> 中,如下所示

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <style jsx global>{`
        html {
          font-family: ${inter.style.fontFamily};
        }
      `}</style>
      <Component {...pageProps} />
    </>
  )
}

单页使用

要在单个页面上使用字体,请将其添加到特定页面,如下所示

pages/index.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function Home() {
  return (
    <div className={inter.className}>
      <p>Hello World</p>
    </div>
  )
}

指定子集

Google 字体会自动进行 子集化。这减小了字体文件的大小并提高了性能。你需要定义你想要预加载的这些子集中的哪些。如果 preloadtrue,但未指定任何子集,则会发出警告。

这可以通过将其添加到函数调用中来完成

pages/_app.js
const inter = Inter({ subsets: ['latin'] })

查看 Font API 参考 以获取更多信息。

使用多种字体

你可以在你的应用中导入和使用多种字体。你可以采用两种方法。

第一种方法是创建一个实用程序函数,该函数导出字体,导入它,并在需要时应用其 className。这确保了字体仅在渲染时才预加载

app/fonts.ts
import { Inter, Roboto_Mono } from 'next/font/google'
 
export const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})
 
export const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
})

在上面的示例中,Inter 将全局应用,而 Roboto Mono 可以根据需要导入和应用。

或者,你可以创建一个 CSS 变量 并将其与你首选的 CSS 解决方案一起使用

app/global.css
html {
  font-family: var(--font-inter);
}
 
h1 {
  font-family: var(--font-roboto-mono);
}

在上面的示例中,Inter 将全局应用,任何 <h1> 标签都将使用 Roboto Mono 样式。

建议:谨慎使用多种字体,因为每种新字体都是客户端必须下载的额外资源。

本地字体

导入 next/font/local 并指定你的本地字体文件的 src。我们建议使用 可变字体 以获得最佳性能和灵活性。

pages/_app.js
import localFont from 'next/font/local'
 
// Font files can be colocated inside of `pages`
const myFont = localFont({ src: './my-font.woff2' })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={myFont.className}>
      <Component {...pageProps} />
    </main>
  )
}

如果你想为单个字体系列使用多个文件,src 可以是一个数组

const roboto = localFont({
  src: [
    {
      path: './Roboto-Regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: './Roboto-Italic.woff2',
      weight: '400',
      style: 'italic',
    },
    {
      path: './Roboto-Bold.woff2',
      weight: '700',
      style: 'normal',
    },
    {
      path: './Roboto-BoldItalic.woff2',
      weight: '700',
      style: 'italic',
    },
  ],
})

查看 Font API 参考 以获取更多信息。

与 Tailwind CSS 结合使用

next/font 可以通过 CSS 变量Tailwind CSS 结合使用。

在下面的示例中,我们使用来自 next/font/google 的字体 Inter(你可以使用来自 Google 或本地字体的任何字体)。使用 variable 选项加载你的字体以定义你的 CSS 变量名称,并将其分配给 inter。然后,使用 inter.variable 将 CSS 变量添加到你的 HTML 文档中。

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={`${inter.variable} font-sans`}>
      <Component {...pageProps} />
    </main>
  )
}

最后,将 CSS 变量添加到你的 Tailwind CSS 配置

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    './app/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-inter)'],
        mono: ['var(--font-roboto-mono)'],
      },
    },
  },
  plugins: [],
}

你现在可以使用 font-sansfont-mono 实用程序类将字体应用于你的元素。

预加载

当在站点的页面上调用字体函数时,它不是全局可用的,也不会在所有路由上预加载。相反,字体仅在相关的路由上预加载,具体取决于它使用的文件类型

  • 如果它是一个 独特的页面,它会在该页面的独特路由上预加载
  • 如果它在 自定义 App 中,它会在站点下 /pages 的所有路由上预加载

重用字体

每次你调用 localFont 或 Google 字体函数时,该字体都会作为你应用中的一个实例托管。因此,如果你在多个文件中加载相同的字体函数,则会托管同一字体的多个实例。在这种情况下,建议执行以下操作

  • 在一个共享文件中调用字体加载器函数
  • 将其导出为常量
  • 在你想要使用此字体的每个文件中导入常量