字体模块

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

它包含内置的自动自托管功能,适用于任何字体文件。这意味着您可以无 布局偏移 (layout shift) 地最优加载网页字体。

您还可以方便地使用所有 Google 字体。CSS 和字体文件会在构建时下载,并与您的其他静态资源一起自托管。浏览器不会向 Google 发送任何请求。

import { Inter } from 'next/font/google'

// 如果加载的是可变字体,则无需指定字重
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})

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

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

参考

font/googlefont/local类型是否必需
srcCross IconCheck Icon字符串或对象数组
weightCheck IconCheck Icon字符串或数组必需/可选
styleCheck IconCheck Icon字符串或数组-
subsetsCheck IconCross Icon字符串数组-
axesCheck IconCross Icon字符串数组-
displayCheck IconCheck Icon字符串-
preloadCheck IconCheck Icon布尔值-
fallbackCheck IconCheck Icon字符串数组-
adjustFontFallbackCheck IconCheck Icon布尔值或字符串-
variableCheck IconCheck Icon字符串-
declarationsCross IconCheck Icon对象数组-

src

字体文件的路径,可以是字符串或对象数组(类型为 Array<{path: string, weight?: string, style?: string}>),相对于调用字体加载器函数的目录。

用于 next/font/local

  • 必需

示例:

  • src:'./fonts/my-font.woff2',其中 my-font.woff2 放置在 app 目录下的 fonts 目录中
  • src:[{path: './inter/Inter-Thin.ttf', weight: '100',},{path: './inter/Inter-Regular.ttf',weight: '400',},{path: './inter/Inter-Bold-Italic.ttf', weight: '700',style: 'italic',},]
  • 如果在 app/page.tsx 中调用字体加载器函数并使用 src:'../styles/fonts/my-font.ttf',则 my-font.ttf 应放置在项目根目录的 styles/fonts 目录中

weight

字体的 weight,有以下可能:

  • 字符串,值为特定字体可用的字重,或如果是 可变字体 则为范围值
  • 如果不是 Google 可变字体,则为字重值的数组。仅适用于 next/font/google

用于 next/font/googlenext/font/local

示例:

  • weight: '400':单个字重值的字符串 - 对于字体 Inter,可能值为 '100''200''300''400''500''600''700''800''900''variable'(其中 'variable' 为默认值)
  • weight: '100 900':可变字体范围在 100900 之间的字符串
  • weight: ['100','400','900']:非可变字体的三个可能值的数组

style

字体的 style,有以下可能:

  • 字符串 ,默认值为 'normal'
  • 如果不是 Google 可变字体,则为样式值的数组。仅适用于 next/font/google

用于 next/font/googlenext/font/local

  • 可选

示例:

  • style: 'italic':字符串 - 对于 next/font/google 可以是 normalitalic
  • style: 'oblique':字符串 - 对于 next/font/local 可以接受任何值,但预期来自 标准字体样式
  • style: ['italic','normal']next/font/google 的两个值的数组 - 值为 normalitalic

subsets

字体的 subsets,由字符串值数组定义,每个字符串值为您希望 预加载 的子集名称。通过 subsets 指定的字体在 preload 选项为 true(默认值)时会在头部注入链接预加载标签。

用于 next/font/google

  • 可选

示例:

  • subsets: ['latin']:包含子集 latin 的数组

您可以在 Google 字体页面上找到字体的所有子集列表。

axes

某些可变字体具有可以包含的额外 axes。默认情况下,仅包含字重以保持文件大小较小。axes 的可能值取决于特定字体。

用于 next/font/google

  • 可选

示例:

  • axes: ['slnt']:包含值 slnt 的数组,用于 Inter 可变字体,该字体具有 slnt 作为额外 axes,如 此处 所示。您可以通过在 Google 可变字体页面 上使用过滤器并查找除 wght 之外的 axes 来找到字体的可能 axes

display

字体的 display,可能的字符串 'auto''block''swap''fallback''optional',默认值为 'swap'

用于 next/font/googlenext/font/local

  • 可选

示例:

  • display: 'optional':分配给 optional 值的字符串

preload

布尔值,指定是否应 预加载 字体。默认为 true

用于 next/font/googlenext/font/local

  • 可选

示例:

  • preload: false

fallback

如果无法加载字体,则使用的回退字体。无默认值的回退字体字符串数组。

  • 可选

用于 next/font/googlenext/font/local

示例:

  • fallback: ['system-ui', 'arial']:将回退字体设置为 system-uiarial 的数组

adjustFontFallback

用于 next/font/googlenext/font/local

  • 可选

示例:

  • adjustFontFallback: false:用于 next/font/google
  • adjustFontFallback: 'Times New Roman':用于 next/font/local

variable

字符串值,定义如果样式通过 CSS 变量方法 应用时使用的 CSS 变量名称。

用于 next/font/googlenext/font/local

  • 可选

示例:

  • variable: '--my-font':声明 CSS 变量 --my-font

declarations

字体面 描述符 键值对数组,进一步定义生成的 @font-face

用于 next/font/local

  • 可选

示例:

  • declarations: [{ prop: 'ascent-override', value: '90%' }]

示例

Google 字体

要使用 Google 字体,请从 next/font/google 导入它作为函数。我们建议使用 可变字体 以获得最佳性能和灵活性。

import { Inter } from 'next/font/google'

// 如果加载的是可变字体,则无需指定字重
const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
})

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

如果无法使用可变字体,您将需要指定字重

import { Roboto } from 'next/font/google'

const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
  display: 'swap',
})

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

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

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

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

指定子集

Google 字体会自动 子集化。这会减小字体文件的大小并提高性能。您需要定义要预加载哪些子集。如果 preloadtrue 但未指定任何子集,将导致警告。

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

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

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

使用多种字体

您可以在应用程序中导入并使用多种字体。有两种方法可以实现。

第一种方法是创建一个工具函数来导出字体,导入它,并在需要的地方应用其 className。这样可以确保字体仅在渲染时预加载:

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',
})
import { inter } from './fonts'

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

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

或者,您可以创建一个 CSS 变量 并使用您喜欢的 CSS 解决方案:

import { Inter, Roboto_Mono } from 'next/font/google'
import styles from './global.css'

const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
  display: 'swap',
})

const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  variable: '--font-roboto-mono',
  display: 'swap',
})

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
      <body>
        <h1>我的应用</h1>
        <div>{children}</div>
      </body>
    </html>
  )
}
app/global.css
html {
  font-family: var(--font-inter);
}

h1 {
  font-family: var(--font-roboto-mono);
}

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

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

本地字体

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

import localFont from 'next/font/local'

// 字体文件可以放在 `app` 内部
const myFont = localFont({
  src: './my-font.woff2',
  display: 'swap',
})

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

如果要对单个字体系列使用多个文件,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',
    },
  ],
})

查看 字体 API 参考 获取更多信息。

与 Tailwind CSS 一起使用

next/font 通过 CSS 变量Tailwind CSS 无缝集成。

在下面的示例中,我们使用来自 next/font/googleInterRoboto_Mono 字体(您可以使用任何 Google 字体或本地字体)。使用 variable 选项定义 CSS 变量名称,例如分别为这些字体定义 interroboto_mono。然后,应用 inter.variableroboto_mono.variable 将 CSS 变量包含在您的 HTML 文档中。

须知:您可以根据您的偏好、样式需求或项目要求,将这些变量添加到 <html><body> 标签中。

import { Inter, Roboto_Mono } from 'next/font/google'

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-inter',
})

const roboto_mono = Roboto_Mono({
  subsets: ['latin'],
  display: 'swap',
  variable: '--font-roboto-mono',
})

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

最后,将 CSS 变量添加到您的 Tailwind CSS 配置 中:

Tailwind CSS v4

Tailwind v4 开始,默认情况下不需要任何配置。如果您确实需要配置 Tailwind,可以按照 官方文档 配置全局 CSS 文件。

global.css
@import "tailwindcss";

@theme inline {
  --font-sans: var(--font-inter);
  --font-mono: var(--font-roboto-mono);
}

Tailwind CSS v3

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 工具类将字体应用到您的元素上。

<p class="font-sans ...">The quick brown fox ...</p>
<p class="font-mono ...">The quick brown fox ...</p>

应用样式

您可以通过三种方式应用字体样式:

className

返回一个只读的 CSS className,用于传递给 HTML 元素的加载字体。

<p className={inter.className}>Hello, Next.js!</p>

style

返回一个只读的 CSS style 对象,用于传递给 HTML 元素的加载字体,包括 style.fontFamily 以访问字体系列名称和回退字体。

<p style={inter.style}>Hello World</p>

CSS 变量

如果您希望在外部样式表中设置样式并在那里指定其他选项,请使用 CSS 变量方法。

除了导入字体外,还要导入定义了 CSS 变量的 CSS 文件,并按如下方式设置字体加载器对象的 variable 选项:

import { Inter } from 'next/font/google'
import styles from '../styles/component.module.css'

const inter = Inter({
  variable: '--font-inter',
})

要使用字体,将文本的父容器的 className 设置为字体加载器的 variable 值,并将文本的 className 设置为来自外部 CSS 文件的 styles 属性。

<main className={inter.variable}>
  <p className={styles.text}>Hello World</p>
</main>

component.module.css CSS 文件中定义 text 选择器类如下:

styles/component.module.css
.text {
  font-family: var(--font-inter);
  font-weight: 200;
  font-style: italic;
}

在上面的示例中,文本 Hello World 使用 Inter 字体和生成的字体回退样式,font-weight: 200font-style: italic

使用字体定义文件

每次调用 localFont 或 Google 字体函数时,该字体将在您的应用程序中作为一个实例托管。因此,如果您需要在多个地方使用相同的字体,您应该在一个地方加载它,并在需要的地方导入相关的字体对象。这可以通过字体定义文件完成。

例如,在应用程序目录的根目录下创建一个 styles 文件夹,并在其中创建一个 fonts.ts 文件。

然后,按如下方式指定您的字体定义:

import { Inter, Lora, Source_Sans_3 } from 'next/font/google'
import localFont from 'next/font/local'

// 定义您的可变字体
const inter = Inter()
const lora = Lora()
// 定义一个非可变字体的两种权重
const sourceCodePro400 = Source_Sans_3({ weight: '400' })
const sourceCodePro700 = Source_Sans_3({ weight: '700' })
// 定义一个自定义本地字体,其中 GreatVibes-Regular.ttf 存储在 styles 文件夹中
const greatVibes = localFont({ src: './GreatVibes-Regular.ttf' })

export { inter, lora, sourceCodePro400, sourceCodePro700, greatVibes }

您现在可以在代码中使用这些定义,如下所示:

import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'

export default function Page() {
  return (
    <div>
      <p className={inter.className}>使用 Inter 字体的 Hello world</p>
      <p style={lora.style}>使用 Lora 字体的 Hello world</p>
      <p className={sourceCodePro700.className}>
        使用 Source_Sans_3 字体且权重为 700 的 Hello world
      </p>
      <p className={greatVibes.className}>使用 Great Vibes 字体的标题</p>
    </div>
  )
}

为了更轻松地在代码中访问字体定义,您可以在 tsconfig.jsonjsconfig.json 文件中定义路径别名,如下所示:

tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "@/fonts": ["./styles/fonts"]
    }
  }
}

您现在可以按如下方式导入任何字体定义:

import { greatVibes, sourceCodePro400 } from '@/fonts'

预加载

当在您网站的某个页面上调用字体函数时,它不会全局可用,也不会在所有路由上预加载。相反,字体仅根据使用它的文件类型在相关路由上预加载:

  • 如果是 唯一页面,它将在该页面的唯一路由上预加载。
  • 如果是 布局,它将在布局包装的所有路由上预加载。
  • 如果是 根布局,它将在所有路由上预加载。

版本变更

版本变更
v13.2.0@next/font 重命名为 next/font。不再需要安装。
v13.0.0添加了 @next/font