Font Module
next/font
会自动优化你的字体(包括自定义字体),并移除外部网络请求,从而提升隐私和性能。
它为任意字体文件提供内置自动自托管。这意味着你可以无布局偏移地(layout shift)最佳加载 Web 字体。
你还可以便捷地使用所有 Google Fonts。CSS 和字体文件会在构建时下载,并与其他静态资源一起自托管。浏览器不会向 Google 发送任何请求。
要在所有页面中使用字体,请将其添加到 /pages
下的 _app.js
文件:
import { Inter } from 'next/font/google'
// 加载可变字体时,无需指定 font weight
const inter = Inter({ subsets: ['latin'] })
export default function MyApp({ Component, pageProps }) {
return (
<main className={inter.className}>
<Component {...pageProps} />
</main>
)
}
🎥 视频讲解: 了解更多关于
next/font
的用法 → YouTube(6 分钟)。
参考
| 键 | font/google
| font/local
| 类型 | 是否必填 |
| ------------------------------------------- | ------------------- | ------------------- | -------------------------- | ----------------- |
| src
| ❌ | ✅ | 字符串或对象数组 | 是 |
| weight
| ✅ | ✅ | 字符串或数组 | 必填/可选 |
| style
| ✅ | ✅ | 字符串或数组 | - |
| subsets
| ✅ | ❌ | 字符串数组 | - |
| axes
| ✅ | ❌ | 字符串数组 | - |
| display
| ✅ | ✅ | 字符串 | - |
| preload
| ✅ | ✅ | 布尔值 | - |
| fallback
| ✅ | ✅ | 字符串数组 | - |
| adjustFontFallback
| ✅ | ✅ | 布尔值或字符串 | - |
| variable
| ✅ | ✅ | 字符串 | - |
| declarations
| ❌ | ✅ | 对象数组 | - |
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
可选值如下:
- 单个权重字符串,或可变字体的权重范围字符串
- 非可变字体可用权重数组,仅适用于
next/font/google
用于 next/font/google
和 next/font/local
- 如果使用的字体不是可变字体,则必填
示例:
weight: '400'
:单个权重字符串——如Inter
可选'100'
、'200'
、'300'
、'400'
、'500'
、'600'
、'700'
、'800'
、'900'
或'variable'
(默认)weight: '100 900'
:可变字体的权重范围weight: ['100','400','900']
:非可变字体的权重数组
style
字体 style
可选值如下:
- 字符串值,默认
'normal'
- 非可变 Google 字体可用样式数组,仅适用于
next/font/google
用于 next/font/google
和 next/font/local
- 可选
示例:
style: 'italic'
:字符 串,可为normal
或italic
(next/font/google
)style: 'oblique'
:字符串,可为任意标准字体样式(next/font/local
)style: ['italic','normal']
:Google 字体的样式数组
subsets
字体 subsets
由字符串数组定义,指定你希望预加载的子集。指定的子集会在 preload
为 true 时自动注入 preload 标签(默认)。
用于 next/font/google
- 可选
示例:
subsets: ['latin']
:包含latin
子集的数组
所有可用子集可在 Google Fonts 页面查看。
axes
部分可变字体有额外的 axes
可选。默认只包含字体权重以减小文件体积。可选值取决于具体字体。
用于 next/font/google
- 可选
示例:
axes: ['slnt']
:如Inter
可变字体的slnt
轴。可在 Google 可变字体页面 查看所有可用轴。
display
字体 display
可选值为 'auto'
、'block'
、'swap'
、'fallback'
或 'optional'
,默认 'swap'
。
用于 next/font/google
和 next/font/local
- 可选
示例:
display: 'optional'
:设置为optional
preload
布尔值,指定是否预加载字体。默认 true
。
用于 next/font/google
和 next/font/local
- 可选
示例:
preload: false
fallback
字体加载失败时的备用字体。为字符串数组,无默认值。
- 可选
用于 next/font/google
和 next/font/local
示例:
fallback: ['system-ui', 'arial']
:设置备用字体为system-ui
或arial
adjustFontFallback
- 对于
next/font/google
:布尔值,指定是否自动使用备用字体以减少布局偏移。默认true
。 - 对于
next/font/local
:字符串或布尔值false
,可选'Arial'
、'Times New Roman'
或false
,默认'Arial'
。
用于 next/font/google
和 next/font/local
- 可选
示例:
adjustFontFallback: false
:next/font/google
adjustFontFallback: 'Times New Roman'
:next/font/local
variable
字符串,用于定义 CSS 变量名(CSS 变量用法)。
用于 next/font/google
和 next/font/local
- 可选
示例:
variable: '--my-font'
:声明 CSS 变量--my-font
declarations
字体 face 描述符 的键值对数组,用于进一步定义生成的 @font-face
。
用于 next/font/local
- 可选
示例:
declarations: [{ prop: 'ascent-override', value: '90%' }]
示例
Google Fonts
要使用 Google 字体,从 next/font/google
以函数方式导入。推荐使用可变字体以获得最佳性能和灵活性。
要在所有页面中使用字体,请将其添加到 /pages
下的 _app.js
文件:
import { Inter } from 'next/font/google'
// 加载可变字体时,无需指定 font weight
const inter = Inter({ subsets: ['latin'] })
export default function MyApp({ Component, pageProps }) {
return (
<main className={inter.className}>
<Component {...pageProps} />
</main>
)
}
如果无法使用可变字体,必须指定权重:
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>
)
}
你可以通过数组指定多个权重和/或样式:
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})
提示: 多单词字体名请用下划线(_)连接。例如
Roboto Mono
应导入为Roboto_Mono
。
在 <head>
中应用字体
你也可以不使用 wrapper 和 className
,而是在 <head>
中注入样式:
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} />
</>
)
}
单页面使用
要在单个页面中使用字体,直接在该页面引入:
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 Fonts 会自动子集化,以减小字体文件体积并提升性能。你需要定义要预加载的子集。如果 preload
为 true
却未指定子集,会收到警告。
只需在函数调用时添加:
const inter = Inter({ subsets: ['latin'] })
详见 Font API 参考。
多字体使用
你可以在应用中导入并使用多个字体。有两种方式:
第一种方式是创建一个工具函数导出字体,并在需要的地方导入并应用其 className
。这样只有在渲染时才会预加载字体:
- TypeScript
- JavaScript
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, 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 方案使用:
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'
// 字体文件可与 `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
可与 Tailwind CSS 无缝集成,使用 CSS 变量。
如下示例,使用 next/font/google
的 Inter
和 Roboto_Mono
字体(你也可以用任意 Google 字体或本地字体)。通过 variable
选项定义 CSS 变量名,然后在 HTML 文档中应用。
提示: 你可以将这些变量加到
<html>
或<body>
标签,具体取决于你的需求和项目风格。
import { Inter } from 'next/font/google'
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
})
const roboto_mono = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
variable: '--font-roboto-mono',
})
export default function MyApp({ Component, pageProps }) {
return (
<main className={`${inter.variable} ${roboto_mono.variable} font-sans`}>
<Component {...pageProps} />
</main>
)
}
最后,在 Tailwind CSS 配置中添加 CSS 变量:
Tailwind CSS v4
自 Tailwind v4 起,默认无需配置。如需自定义配置,请参考官方文档。
@import 'tailwindcss';
@theme inline {
--font-sans: var(--font-inter);
--font-mono: var(--font-roboto-mono);
}
Tailwind CSS v3
/** @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-sans
和 font-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 变量的样式文件,并在字体加载对象中设置 variable 选项:
- TypeScript
- JavaScript
import { Inter } from 'next/font/google'
import styles from '../styles/component.module.css'
const inter = Inter({
variable: '--font-inter',
})
import { Inter } from 'next/font/google'
import styles from '../styles/component.module.css'
const inter = Inter({
variable: '--font-inter',
})
要使用字体,将父容器的 className
设为字体加载器的 variable
,文本的 className
设为外部 CSS 文件的样式:
- TypeScript
- JavaScript
<main className={inter.variable}>
<p className={styles.text}>Hello World</p>
</main>
<main className={inter.variable}>
<p className={styles.text}>Hello World</p>
</main>
在 component.module.css
文件中定义 text
选择器:
.text {
font-family: var(--font-inter);
font-weight: 200;
font-style: italic;
}
如上,Hello World
文本使用 Inter
字体及生成的备用字体,权重 200,斜体。
使用字体定义文件
每次调用 localFont
或 Google 字体函数,都会在应用中托管一个字体实例。因此,如需多处使用同一字体,建议集中加载并导出字体对象。
例如,在 app 根目录的 styles
文件夹下创建 fonts.ts
文件:
- TypeScript
- JavaScript
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, 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 }
你可以在代码中这样使用这些定义:
- TypeScript
- JavaScript
import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'
export default function Page() {
return (
<div>
<p className={inter.className}>Hello world using Inter font</p>
<p style={lora.style}>Hello world using Lora font</p>
<p className={sourceCodePro700.className}>
Hello world using Source_Sans_3 font with weight 700
</p>
<p className={greatVibes.className}>My title in Great Vibes font</p>
</div>
)
}
import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'
export default function Page() {
return (
<div>
<p className={inter.className}>Hello world using Inter font</p>
<p style={lora.style}>Hello world using Lora font</p>
<p className={sourceCodePro700.className}>
Hello world using Source_Sans_3 font with weight 700
</p>
<p className={greatVibes.className}>My title in Great Vibes font</p>
</div>
)
}
为便于在代码中访问字体定义,可在 tsconfig.json
或 jsconfig.json
中定义路径别名:
{
"compilerOptions": {
"paths": {
"@/fonts": ["./styles/fonts"]
}
}
}
现在你可以这样导入字体定义:
- TypeScript
- JavaScript
import { greatVibes, sourceCodePro400 } from '@/fonts'
import { greatVibes, sourceCodePro400 } from '@/fonts'
预加载
当你在站点页面调用字体函数时,字体不会全局可用并在所有路由预加载,而是根据使用的文件类型,仅在相关路由预加载:
版本变更
| 版本 | 变更内容 |
| --------- | -------------------------------------------------------------- |
| v13.2.0
| @next/font
更名为 next/font
,无需单独安装。 |
| v13.0.0
| @next/font
新增。 |