Next.js App Router下Chart.js/React-Chartjs-2字体配置失败求助
解决Next.js App Router中Chart.js无法加载next/google-font字体的问题
问题核心
你通过next/font/google导入的Saira Extra Condensed字体在全局body生效,但Chart.js渲染时却 fallback到Times New Roman,其他字体(如Roboto)正常,本质是next/font的字体范围隔离机制和Chart.js canvas渲染的字体加载时机/访问权限不匹配导致的。
具体解决步骤
1. 解除字体范围限制,让全局可访问
next/font默认会给字体生成唯一类名并做范围隔离,canvas上下文可能无法直接读取到。修改layout.tsx的字体配置,添加全局CSS变量:
import { Saira_Extra_Condensed } from 'next/font/google' const sairaFont = Saira_Extra_Condensed({ weight: ['400', '500', '600', '700'], subsets: ['latin'], // 添加全局变量,方便全局引用 variable: '--font-saira', }) export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> {/* 把变量挂载到body,确保全局生效 */} <body className={`${sairaFont.variable} ${sairaFont.className}`}> {children} </body> </html> ) }
2. 监听字体加载状态,配置Chart.js使用目标字体
Chart.js的canvas可能在字体加载完成前就执行绘制,导致 fallback。需要先确认字体加载完成,再初始化图表:
'use client' import { useEffect, useState } from 'react' import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, Font } from 'chart.js' import { Bar } from 'react-chartjs-2' import { sairaFont } from '@/app/layout' // 导入全局字体配置 // 注册Chart.js依赖组件 ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend) // 全局配置Chart.js字体 Font.defaults.family = "'Saira Extra Condensed', sans-serif" Font.defaults.weight = '400' // 匹配你导入的字重 export default function MyChart() { const [isFontLoaded, setIsFontLoaded] = useState(false) useEffect(() => { // 等待字体加载完成再渲染图表 const loadFont = async () => { await sairaFont.load() setIsFontLoaded(true) } loadFont() }, []) // 字体未加载时显示占位 if (!isFontLoaded) return <div>Loading chart...</div> const options = { responsive: true, plugins: { title: { display: true, text: '示例图表', // 局部配置再次指定字体,确保生效 font: { family: "'Saira Extra Condensed', sans-serif", weight: '600', size: 24, }, }, }, } const data = { labels: ['一月', '二月', '三月', '四月', '五月'], datasets: [ { label: '数据', data: [12, 19, 3, 5, 2], backgroundColor: 'rgba(255, 99, 132, 0.2)', borderColor: 'rgba(255, 99, 132, 1)', borderWidth: 1, }, ], } return <Bar options={options} data={data} /> }
3. 兜底:强制canvas继承字体
如果以上方法仍无效,直接给canvas元素设置font-family,确保上下文能读取到:
/* 全局CSS文件或组件内的style标签 */ canvas { font-family: var(--font-saira), sans-serif !important; }
关键注意点
- 字体名称必须完全匹配:
'Saira Extra Condensed'要和导入的字体名一致,大小写、空格不能错。 - 字重要对应:配置中指定的weight必须是你在
next/font中导入的(400/500/600/700),否则会触发字体 fallback。 - 必须标记
'use client':Chart.js和react-chartjs-2是客户端组件,Next.js App Router中要显式声明。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

