You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:54:49