Next.js 13 与 Tailwind CSS 集成自定义本地字体
问题概述
在 Next.js 13 项目中结合 Tailwind CSS 使用自定义本地字体时,开发者常会遇到字体无法正确加载或应用的问题。典型表现包括:
- 配置了
@next/font/local
但页面未显示预期字体 - Tailwind 未正确识别自定义字体变量
- 多字重(如粗体、斜体)处理困难
- 字体路径引用错误导致404错误
根本原因通常在于配置步骤遗漏关键环节,未能完整实现 Next.js 的字体优化机制与 Tailwind 样式的集成。
完整解决方案
前置准备
移除旧包(如已安装)
bashnpm uninstall @next/font
字体文件放置 将字体文件(如
.woff2
)放入/public/fonts
目录public/ └── fonts/ ├── Surt-Normal-Regular.woff2 ├── Surt-Normal-Bold.woff2 └── Surt-Normal-Semibold-Italic.woff2
路径提示
Next.js 会自动提供 /public
目录下的文件,因此无需自定义路由
步骤1: 配置字体加载
使用 app/
目录(推荐方式)
在 /app/layout.tsx
中配置:
jsx
import localFont from 'next/font/local';
// 配置多个字重变体
const surt = localFont({
src: [
{
path: '../public/fonts/Surt-Normal-Regular.woff2',
weight: '400',
style: 'normal'
},
{
path: '../public/fonts/Surt-Normal-Bold.woff2',
weight: '700',
style: 'normal'
},
{
path: '../public/fonts/Surt-Normal-Semibold-Italic.woff2',
weight: '600',
style: 'italic'
}
],
variable: '--font-surt' // 统一的CSS变量名
});
export default function RootLayout({ children }) {
return (
<html lang="zh-CN" className={`${surt.variable} font-sans`}>
<body>{children}</body>
</html>
);
}
重要提醒
必须同时设置变量 ${surt.variable}
和基础类 font-sans
使用 pages/
目录(传统方式)
在 pages/_app.js
中:
jsx
import localFont from 'next/font/local';
const surt = localFont({
/* 同上配置 */
});
export default function MyApp({ Component, pageProps }) {
return (
<main className={`${surt.variable} font-sans`}>
<Component {...pageProps} />
</main>
);
}
步骤2: 配置 Tailwind CSS
更新 tailwind.config.js
:
js
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./src/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
fontFamily: {
sans: ['var(--font-surt)', 'sans-serif']
},
},
},
plugins: [],
};
步骤3: 在组件中使用
jsx
export default function AboutPage() {
return (
<div>
{/* 使用常规字体 */}
<p className="font-sans">常规文本</p>
{/* 使用粗体 */}
<h1 className="font-sans font-bold">标题文本</h1>
{/* 使用斜体 */}
<blockquote className="font-sans italic">引用内容</blockquote>
</div>
);
}
关键实现机制
字体优化机制
- Next.js 自动生成
@font-face
规则 - 字体文件被预加载,消除布局偏移
- 支持字体显示策略(
display: swap
默认开启)
- Next.js 自动生成
CSS变量集成
css:root { --font-surt: 'Surt__Subset'; } .font-sans { font-family: var(--font-surt), ui-sans-serif, sans-serif; }
多字重处理逻辑
jssrc: [ { path: '...', weight: '400', style: 'normal' }, { path: '...', weight: '700', style: 'normal' } ]
Next.js 会根据实际使用的字重自动加载对应文件
常见问题解决
问题现象 | 解决方案 |
---|---|
字体仍未生效 | 检查 <html> 或 <main> 标签是否设置了 className={surt.variable} |
控制台报告路径错误 | 确保路径从项目根目录开始计算,使用相对路径 ../public/fonts/... |
只有部分字重生效 | 在 src 数组中确保所有字重/样式组合已定义 |
字体闪烁 (FOUT) | 在 localFont 配置中添加 display: 'swap' |
版本兼容性
如果你的项目使用 Next.js v13.1 或更低版本,需安装 @next/font
而非 next/font
。从 v13.2 开始该功能已整合至核心包
最佳实践建议
优先使用 WOFF2 格式
- 现代浏览器支持更优的压缩比
- 文件体积比 TTF 小约 30%
按需加载字重
js// 只加载实际使用的字重 src: isProduction ? [{ path: '...', weight: '400' }] : [...]
创建字体工具函数 在
/lib/fonts.js
中:jsexport function getSurtFont() { return localFont({ src: [...], variable: '--font-surt' }); }
遵循此完整解决方案,你可在 Next.js 13 项目中无缝集成自定义本地字体到 Tailwind CSS,同时享受 Next.js 的字体优化优势。