在Next js API路由中使用字体

pdkcd3nj  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(86)

我在Next js API路由中做一些基本的图像处理,我使用sharp将svg文本转换为png。问题是自定义字体没有加载,这似乎导致了错误(尽管这可能无关紧要),Fontconfig error: No writable cache directories。该应用程序部署在Vercel上。
我想知道如何在Next js API路由中加载公共目录中的字体。
我尝试使用next的localFont函数来加载自定义字体,但这似乎只适用于react组件,而不是API路由。

nuypyhwy

nuypyhwy1#

我想我们可能有相同的目标-将SVG转换为PNG以获得更好的跨浏览器/设备支持。
我能够解决这个问题,但不能说我知道确切的方法。但这里有一些对我很有帮助的东西。
首先,应该添加一个指向fonts.conf文件的ENV var。你希望这是你的API页面路由运行的路径,这是一个Lambda函数。我以为会像Github上的一些建议一样是/var/task
但是我最终在控制台记录cwd,发现我的monorepo设置导致它们在/var/task/packages/app上运行。我建议导入path并在处理程序中记录path.cwd(),以便为您找到正确的路径。
该配置文件将告诉Fontconfig在哪里可以找到一个可写的缓存目录。Lambda函数的默认值是不可写的,所以你想使用可用的tmp目录。
My env var:

FONTCONFIG_PATH=/var/task/packages/app/fonts

字符串
以下是我的fonts.conf

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/var/task/packages/app/fonts/</dir>
  <cachedir>/tmp/fonts-cache/</cachedir>
  <config></config>
</fontconfig>


我把这个文件放在NextJS应用根目录下的fonts目录中,我还把所有自定义字体.ttf文件放在那个目录中。
令人惊讶的是,您需要将字体文件读入无服务器函数-https://vercel.com/guides/how-can-i-use-files-in-serverless-functions
下面是我如何获取API页面路由来拉入我的字体和处理程序开头的fonts.conf

const fontsDir = path.join(process.cwd(), "fonts");
  console.log(`Checking fonts in: ${fontsDir}`);
  fs.readdir(fontsDir, (err, files) => {
    if (err) {
      console.error("Error reading fonts directory:", err);
    } else {
      console.log("Available fonts:", files);
    }
  });


您可能还希望确保该高速缓存目录可用。奇怪的是,如果没有这个,后续的无服务器函数运行将使用与前一次调用相同的字体。我在不同的图像中使用不同的字体,如果您只使用一种字体,这可能没有必要。

fs.mkdirSync(path.resolve(process.cwd(), "tmp", "fonts-cache"), {
    recursive: true,
  });


所有这些都到位后,夏普正在缓慢但可靠地将我的SVG转换为带有自定义字体的PNG,使我的图像在iPhone上看起来比SVG好得多。我发现的唯一问题是夏普在某些字体上应用了与桌面浏览器不同的字距调整,但几乎无法察觉。

相关问题