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目录的静态资源混淆:
- 移动字体文件到
src/fonts/anaheim-variablefont_wght.ttf - 修改
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
相关产品推荐
相关产品推荐

