字体优化
next/font
将自动优化您的字体(包括自定义字体)并移除外部网络请求,从而提高隐私性和性能。
观看: 了解更多关于使用
next/font
的信息 → YouTube(6分钟)。
next/font
包含 内置的自动自托管 功能,可适用于 任何 字体文件。这意味着通过使用底层 CSS size-adjust
属性,可以在没有布局偏移的情况下优化加载网络字体。
这个新的字体系统还允许您在考虑性能和隐私的情况下方便地使用所有 Google Fonts。CSS 和字体文件将在构建时下载,并与其他静态资产一起自托管。浏览器不会向 Google 发送任何请求。
Google 字体
自动自托管任何 Google 字体。字体会被包含在部署中,并从与您的部署相同的域名提供服务。浏览器不会向 Google 发送任何请求。
首先从 next/font/google
中导入您想要使用的字体作为一个函数。我们建议使用可变字体以获得最佳性能和灵活性。
// app/layout.tsx 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> ); }
如果您不能使用可变字体,则 需要指定字体权重:
// app/layout.tsx 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 字体会自动进行子集化。这会减少字体文件的大小并提高性能。您需要定义要预加载的这些子集。如果在 preload
为 true
的情况下未指定任何子集,将会导致警告。
这可以通过将其添加到函数调用中来实现:
// app/layout.tsx const inter = Inter({ subsets: ['latin'] });
查看 字体 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', });
// app/layout.tsx 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> ); }
// app/page.tsx import { roboto_mono } from './fonts'; export default function Page() { return ( <> <h1 className={roboto_mono.className}>My page</h1> </> ); }
在上面的示例中,Inter
将全局应用,Roboto Mono
可以根据需要导入并应用。
或者,您可以创建一个 CSS 变量,并将其与您首选的 CSS 解决方案一起使用:
// app/layout.tsx 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> ); }
// app/global.css html { font-family: var(--font-inter); } h1 { font-family: var(--font-roboto-mono); }
在上面的示例中,Inter
将全局应用,而任何 <h1>
标签将使用 Roboto Mono
样式。
建议: 谨慎使用多种字体,因为每种新字体都是客户端必须下载的额外资源。
本地字体
导入 next/font/local
并指定本地图字体文件的 src
。我们建议使用可变字体以获得最佳性能和灵活性。
// app/layout.tsx 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
(您可以使用来自 Google 或本地字体的任何字体)。使用 variable
选项加载字体以定义 CSS 变量名称并将其分配给 inter
。然后,使用 inter.variable
将 CSS 变量添加到您的 HTML 文档中。
// app/layout.tsx 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}`}> <body>{children}</body> </html> ); }
最后在您的 Tailwind CSS 配置中添加 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-sans
和 font-mono
实用程序类将字体应用到您的元素上。
预加载
当在网站的页面上调用字体函数时,该字体不会在所有路由上全局可用并预加载。相反,字体仅在相关路由上根据使用的文件类型进行预加载:
重复使用字体
每次调用 localFont
或 Google 字体函数时,该字体都会作为一个实例在您的应用中托管。因此,如果您在多个文件中加载相同的字体函数,将会托管多个相同字体的实例。在这种情况下,建议您执行以下操作:
- 在一个共享文件中调用字体加载函数。
- 将其导出为常量。
- 在您想要使用该字体的每个文件中导入该常量。