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

Next.js App Router服务端生成证书时本地字体加载失败求助

解决Canvas本地字体注册不生效问题

针对你在Next.js服务端生成数字证书时,本地字体无法生效的问题,可按以下步骤排查解决:

1. 调整字体注册时机(关键)

将字体注册移到API路由模块的顶部,在服务器启动时全局注册一次,而非每次请求时重复注册。Next.js的API路由模块在服务启动时仅加载一次,全局注册能避免请求级注册的潜在冲突。

修改代码如下:

import fs from 'fs';
import path from 'path';
import { createCanvas, loadImage, registerFont, Canvas } from 'canvas';

// 模块级别注册字体,服务器启动时执行一次
const fontPath = path.join(process.cwd(), 'src', 'fonts', 'fredoka', 'Fredoka-Regular.ttf');

// 先验证字体文件是否存在
if (!fs.existsSync(fontPath)) {
  console.error(`字体文件不存在,请检查路径:${fontPath}`);
} else {
  registerFont(fontPath, { family: 'Fredoka' });
  // 打印已注册字体,确认是否成功加载
  console.log('当前已注册字体列表:', Canvas.getFonts());
}

export async function POST(request: Request) {
  const { name, age} = await request.json()

  const image = await loadImage('https://www.myImage/demo.png');

  const canvas = createCanvas(image.width, image.height);
  const context = canvas.getContext('2d');
  context.drawImage(image, 0, 0);

  // 字体名称加单引号,避免特殊字符或空格导致的识别问题
  context.font = `120px 'Fredoka'`;
  context.textAlign = 'center';
  context.fillStyle = 'black';
  context.fillText(name, 1000, 880);

  context.font = '40px Verdana';
  context.fillStyle = 'black';
  context.fillText(age, 670, 1675);

  const buffer = canvas.toBuffer();
  const outputPath = path.join(process.cwd(), 'public', 'images', `${name}.png`);
  fs.writeFileSync(outputPath, buffer);

  return new Response(JSON.stringify({ message: "image created" }));
};

2. 验证字体路径与权限

  • 查看服务器控制台打印的字体路径,手动确认文件是否存在于对应位置;
  • Linux/macOS环境下,确保字体文件有可读权限:执行chmod 644 src/fonts/fredoka/Fredoka-Regular.ttf;
  • Windows环境下,确认字体文件未被系统锁定或权限受限。

3. 匹配字体真实家族名称

部分字体的内部家族名称与文件名不一致,可通过以下方式确认:

  • macOS:打开「字体册」,选中字体查看「PostScript名称」;
  • Windows:右键字体文件→「属性」→「详细信息」→「字体名称」;
  • 将registerFont的family参数设置为该真实名称,确保完全匹配。

4. 升级Canvas依赖

旧版本canvas包可能存在字体注册bug,执行命令升级到最新版:

npm install canvas@latest

5. 部署环境适配

若部署到Vercel/Netlify等平台:

  • 检查.gitignore是否排除了字体文件夹,确保src/fonts被包含在部署包中;
  • 确认服务端函数的工作目录为项目根目录,process.cwd()指向正确路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:42:36