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

Next.js 13 App目录生成Open Graph图片时字体文件报错求助

问题排查与解决方案

核心问题分析

从错误截图和代码来看,主要存在两个关键问题:

  1. Edge Runtime下的字体文件加载方式错误:fetch(new URL("../../public/Inter-SemiBold.ttf", import.meta.url)) 在Edge环境中无法正确读取本地public目录的字体文件——Edge Runtime不支持直接访问本地文件系统路径。
  2. 字体权重配置不匹配:你使用的是Inter-SemiBold.ttf(字重为600),但代码中配置的weight: 400,导致字体无法正确匹配加载。

修复步骤

方案一:使用Base64嵌入字体(推荐Edge环境使用)

将字体文件转换为Base64字符串直接嵌入代码,规避文件路径问题:

  1. 把public/Inter-SemiBold.ttf转换为Base64:可使用在线工具,或在终端执行命令:
    base64 public/Inter-SemiBold.ttf > inter-semi-bold-base64.txt
    
  2. 修改代码替换字体加载逻辑:
    import { ImageResponse } from 'next/server'
    
    export const runtime = 'edge'
    export const alt = "Online Personal Portfolio"
    export const size = { width: 1200, height: 630 }
    export const contentType = 'image/png'
    
    // 替换为你的Base64字符串(去掉开头的data:font/ttf;base64,前缀)
    const interSemiBoldBase64 = '你的Base64字符串内容'
    const interSemiBold = Buffer.from(interSemiBoldBase64, 'base64')
    
    export default async function Image() {
        return new ImageResponse(
            (
                <div tw='flex flex-col bg-neutral-900 w-full h-full justify-center items-center'>
                    <p tw='text-4xl text-neutral-100 font-semibold'>
                        Online Personal Portfolio
                    </p>
                </div>
            ),
            {
                ...size,
                fonts: [
                    {
                        name: 'Inter',
                        data: interSemiBold,
                        style: 'normal',
                        weight: 600, // 匹配SemiBold的字重
                    },
                ],
            }
        )
    }
    

方案二:切换到Node.js Runtime并使用fs读取字体

如果可以放弃Edge Runtime,改用Node.js Runtime,可通过文件系统模块读取本地字体:

import { ImageResponse } from 'next/server'
import fs from 'fs/promises'
import path from 'path'

// 切换到Node.js runtime
export const runtime = 'nodejs'

export const alt = "Online Personal Portfolio"
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'

export default async function Image() {
    // 正确获取字体文件的绝对路径
    const fontPath = path.join(process.cwd(), 'public', 'Inter-SemiBold.ttf')
    const fontBuffer = await fs.readFile(fontPath)

    return new ImageResponse(
        (
            <div tw='flex flex-col bg-neutral-900 w-full h-full justify-center items-center'>
                <p tw='text-4xl text-neutral-100 font-semibold'>
                    Online Personal Portfolio
                </p>
            </div>
        ),
        {
            ...size,
            fonts: [
                {
                    name: 'Inter',
                    data: fontBuffer,
                    style: 'normal',
                    weight: 600, // 匹配SemiBold字重
                },
            ],
        }
    )
}

额外注意事项

  • 确保字体文件名和路径完全匹配(Linux环境下区分大小写)
  • 若使用Tailwind的font-semibold类,需保证字体配置的weight与类对应(semibold对应600)
  • Edge Runtime下无法使用Node.js的fs模块,必须用Base64或其他边缘兼容方式加载字体

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:15:35