Google Fonts 官方集成
最直接的答案
在 Next.js 的根布局文件中配置商用免费字体,最快的方法是使用 next/font/google。
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en" className={inter.className}>
<body>{children}</body>
</html>
)
}
这不是什么复杂的技术。一个 import,一个初始化,一个 className。就这样。
Google Fonts 有超过 1400 款字体,全部免费用于商业项目。Next.js 官方维护了这个集成。你不需要去其他地方找。
为什么选择这条路
字体问题本质上是信任问题。
当你在网上搜索"免费商用字体",你会看到各种推荐列表。但是你怎么知道这些字体真的可以商用?你怎么确定授权条款没有陷阱?
Google Fonts 解决了这个信任问题。所有字体都是 Open Font License (OFL) 或 Apache License。清晰、安全、可靠。
Next.js 的 next/font 解决了另一个问题:性能。
传统方式加载字体会导致布局偏移(Layout Shift),影响用户体验和 Core Web Vitals 评分。next/font 在构建时下载字体文件,自动生成 CSS,消除了网络请求延迟和布局闪烁。
这是两个问题的一次性解决方案。
如何选择字体
访问 fonts.google.com,浏览字体列表。
重要的不是找到"最好"的字体,而是找到适合的字体。
适合什么?适合你的内容性质。
技术博客可能需要 Mono 字体用于代码块(如 JetBrains Mono),Sans-serif 字体用于正文(如 Inter、Roboto)。设计类网站可能倾向于更有表现力的字体(如 Playfair Display)。
Google Fonts 支持预览。输入你的实际文本内容,看字体在真实场景下的表现。不要只看设计师给出的示例文本。
选定后,点击字体,复制 Next.js 的导入代码。Google Fonts 界面会自动生成适配 next/font 的代码示例。
大多数字体支持多个权重(weight)。不要一次性加载所有权重。
const inter = Inter({
subsets: ['latin'],
weight: ['400', '700'], // 只加载需要的权重
})
如果你的网站只用到常规(400)和粗体(700),那就只加载这两个。
subsets 参数同理。如果你的内容是纯英文,['latin'] 就够了。加载中文子集会显著增加文件大小。
这些优化不会让你的网站快很多。但它们反映了一个原则:只用你需要的。
超出 Google Fonts
有时 Google Fonts 不够。
你可能需要更独特的字体,或者客户指定了某个特定字体。这时你有两个选择:
1. 使用 next/font/local
下载字体文件(.woff2 格式最优),放在项目的 public/fonts 目录下:
import localFont from 'next/font/local'
const customFont = localFont({
src: '../public/fonts/CustomFont-Regular.woff2',
display: 'swap',
})
export default function RootLayout({ children }) {
return (
<html lang="en" className={customFont.className}>
<body>{children}</body>
</html>
)
}
2. 其他商用免费字体源
- Adobe Fonts:需要 Creative Cloud 订阅,但字体质量极高
- Font Squirrel:提供 100% 免费商用字体,但数量有限
- Bunny Fonts:Google Fonts 的隐私友好替代品,字体库相同
但大多数情况下,你不需要这些。Google Fonts + next/font 已经覆盖了 90% 的需求。
字体即风格的物质化
字体不仅仅是呈现文字的工具。
它是风格的物质化。严肃的产品用 Serif 字体(如 Times New Roman),现代的应用用 Sans-serif(如 Inter)。
选择字体就是选择你想传递的氛围。
这不是关于"哪个字体最美"。美是主观的。重要的是:这个字体是否准确表达了你想传达的调性?
在 RootLayout 中设置字体,意味着你在定义整个应用的基调。这是一个设计决策,不仅仅是技术实现。
一些设计师喜欢混搭多种字体:标题用一种,正文用另一种,代码块再用一种。
这样做可以增加视觉层次感。但也容易翻车。
如果你不确定,就用一种字体。一致性永远是安全的选择。
当你想用多种字体时,确保它们在视觉上有明显区分(如 Serif + Sans-serif),而不是两种相似的 Sans-serif。相似的字体混搭只会让人困惑。
配置即决策
在 RootLayout 中配置字体,看起来是一个小事。
但它强迫你做出决策。什么字体?什么权重?什么子集?
这些决策塑造了你的应用的视觉身份。
Next.js 让这个过程变得容易。但容易不代表随意。选择字体依然需要思考。
Google Fonts 给了你 1400 种选择。但最终,你只能选一种(或几种)。
选择即放弃。你选择了 Inter,就放弃了 Roboto。
这是所有设计工作的本质。
参考资源
Related Posts
Articles you might also find interesting
减少 Next.js 启动时的工作量
开发服务器启动缓慢不是偶然。它在做的事太多了。
动态元数据生成:让机器读懂你的页面
generateMetadata 不只是填写表单。它决定了搜索引擎、社交平台、AI 系统如何理解和呈现你的内容。
继承基础配置
配置不需要重复书写。继承机制让每个层次只表达自己的差异。
Purikura的页面系统
通过五层分层继承复用架构,实现零代码修改的页面生成系统。从类型定义到页面渲染,每一层专注单一职责,实现真正的数据驱动开发。
请求包含 gzip 压缩的任务结果 JSON
数据传输的本质是在空间和时间之间做选择,压缩是对带宽的节约,也是对等待的妥协
引入懒加载模式
懒加载不是优化技巧,而是关于时机的选择。何时创建,决定了系统的效率和复杂度。
让错误浮现
Next.js 构建悬挂问题的根源不在工具,而在掩盖。严格类型检查不是负担,而是质量的守护者。
next-intl localePrefix:默认语言不显示前缀
理解 next-intl 中 localePrefix 配置的设计哲学,以及为什么默认语言不应在 URL 中显现。
next-intl 的服务端与客户端协同机制
理解 next-intl 如何在 Next.js App Router 中协调服务端渲染和客户端交互,以及为什么需要显式设置 locale。
用静态导出控制视口
Next.js 中的视口配置通过静态导出模式定义页面初始状态,理解其背后的设计约束能够更好地控制用户体验边界。
一次一次的代价
在表格的每一行里调用一次查询,看起来最直接。但一次一次累积起来,代价会变得巨大。