Font Optimization
next/font
将自动优化你的字体(包括自定义字体)并移除外部网络请求,以提高隐私和性能。
🎥 观看: 了解更多关于使用
next/font
→ YouTube(6 分钟)。
next/font
包含为任何字体文件提供内置的自动自托管功能。这意味着你可以借助底层 CSS size-adjust
属性,以零布局偏移的方式最佳地加载网络字体。
这个新的字体系统还允许你便捷地使用所有 Google 字体,同时兼顾性能和隐私。CSS 和字体文件在构建时下载,并与你的其他静态资源一起自托管。浏览器不会向 Google 发送任何请求。
Google 字体
自动自托管任何 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>
)
}
你可以通过使用数组来指定多个粗细和/或样式:
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})
值得注意的是:对于多词字体名称,请使用下划线(_)。例如,
Roboto Mono
应该导入为Roboto_Mono
。
指定子集
Google 字体会自动进行子集化。这减小了字体文件的大小并提高了性能。你需要定义要预加载的子集。如果在 preload
为 true
的情况下没有指定任何子集,将会收到警告。
这可以通过将子集添加到函数调用中来完成:
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>
)
}
import { roboto_mono } from './fonts'
export default function Page() {
return (
<>
<h1 className={roboto_mono.className}>My page</h1>
</>
)
}
在上面的例子中,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>My App</h1>
<div>{children}</div>
</body>
</html>
)
}
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/google
中的 Inter
和 Roboto_Mono
字体(你可以使用任何 Google 字体或本地字体)。使用 variable
选项为这些字体定义 CSS 变量名,例如分别为 inter
和 roboto_mono
。然后,应用 inter.variable
和 roboto_mono.variable
以在你的 HTML 文档中包含这些 CSS 变量。
值得注意的是:你可以将这些变量添加到
<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 文件。
@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>
预加载
当在你网站的页面上调用字体函数时,它不会在所有路由上全局可用并预加载。相反,字体仅在基于使用它的文件类型的相关路由上预加载:
重用字体
每次调用 localFont
或 Google 字体函数时,该字体都会作为应用程序中的一个实例托管。因此,如果你在多个文件中加载相同的字体函数,则会托管同一字体的多个实例。在这种情况下,建议执行以下操作:
- 在一个共享文件中调用字体加载器函数
- 将其导出为常量
- 在每个需要使用该字体的文件中导入常量