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

Next.js中next/font/local无法解析public/fonts下TTF字体路径

Next.js localFont 路径解析问题解答

问题背景

项目结构如下:

├── README.md
├── eslint.config.mjs
├── next-env.d.ts
├── next.config.ts
├── package-lock.json
├── package.json
├── postcss.config.mjs
├── public
│   ├── fonts
│   │   └── anaheim-variablefont_wght.ttf
│   └── images
│       ├── fallingheart.svg
│       ├── favicon.ico
│       ├── file.svg
│       ├── globe.svg
│       ├── loadingheart.svg
│       ├── next.svg
│       ├── vercel.svg
│       └── window.svg
├── src
│   ├── app
│   │   ├── globals.css
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── components
│   │   ├── Card.tsx
│   │   ├── Footer.tsx
│   │   └── Navbar.tsx
│   └── libs
│       └── fonts.tsx
├── tailwind.config.ts
├── tree.txt
└── tsconfig.json

/src/libs/fonts.tsx 中的代码:

import localFont from "next/font/local";

export const anaheim = localFont({
  src: [
    {
      path: "/fonts/anaheim-variablefont_wght.ttf",
      weight: "100 900",
    },
  ],
  variable: "--font-Anaheim",
});

export const fonts = `${anaheim.variable}`;

使用根路径 /fonts/anaheim-variablefont_wght.ttf 时构建报错找不到文件,但使用相对路径 ../../public/fonts/anaheim-variablefont_wght.ttf 可正常工作。项目其他部分能正常引用public目录,依赖版本:

  • next@15.1.6
  • postcss@8.4.49
  • react-confetti@6.1.0
  • react-dom@18.3.1
  • react-matter-js@1.0.5
  • react@18.3.1
  • tailwindcss@3.4.17
  • typescript@5.7.2

问题解答

1. 为何next/font/local会出现文件找不到的错误?

next/font/local 的路径解析逻辑和public目录的静态资源引用逻辑完全不同:

  • public目录的根路径(如/fonts/xxx.ttf)是给浏览器端请求静态资源用的,由Next.js的静态资源服务处理。
  • 而localFont是在构建阶段执行的Node.js代码,它需要的是本地文件系统的实际路径,根路径/会被解析为服务器的文件系统根目录(不是项目根目录),自然找不到项目里的字体文件。

2. 为何相对路径可行?按认知public目录不应使用相对路径引用?

这里的相对路径是给Node.js在构建时用的,不是给浏览器用的:

  • localFont在构建时会读取本地文件,相对路径是相对于当前文件(/src/libs/fonts.tsx)的位置来解析的,../../public/fonts/xxx.ttf刚好指向项目中字体文件的实际位置,所以能被正确找到。
  • public目录的根路径引用是浏览器端的用法,和构建阶段的localFont路径解析属于两个不同的场景,二者不冲突。

3. 如何解决该路径解析问题?

有两种推荐的解决方案:

方案一:使用项目根目录相对路径(更清晰)

在fonts.tsx中,利用Node.js的路径工具类拼接项目根目录路径:

import localFont from "next/font/local";
import { fileURLToPath } from "url";
import { dirname, join } from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

export const anaheim = localFont({
  src: [
    {
      path: join(__dirname, "../../public/fonts/anaheim-variablefont_wght.ttf"),
      weight: "100 900",
    },
  ],
  variable: "--font-Anaheim",
});

export const fonts = `${anaheim.variable}`;

方案二:将字体文件移至src目录下(符合Next.js推荐方式)

Next.js推荐将构建时需要处理的私有字体放在src目录下,避免和public目录的静态资源混淆:

  1. 移动字体文件到src/fonts/anaheim-variablefont_wght.ttf
  2. 修改fonts.tsx:
import localFont from "next/font/local";

export const anaheim = localFont({
  src: [
    {
      path: "../fonts/anaheim-variablefont_wght.ttf",
      weight: "100 900",
    },
  ],
  variable: "--font-Anaheim",
});

export const fonts = `${anaheim.variable}`;

内容的提问来源于stack exchange,提问作者Liferafter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 14:17:03