📑

react-pdfでNasuフォントが使えない場合の対処法

2022/09/22に公開

初めに

Next.jsのプロジェクトでPDFを出力する必要があったので, ライブラリの@react-pdf/rendererを使用して実装しようとしたのですがNasuフォントがうまく読み込めず苦戦したので対処法をまとめました。

状況

まず当方が陥った状況について説明します。
react-pdfではNasuフォント以外での日本語出力に対応していないようで, 事前にNasuフォントのttfファイルをダウンロードして, 使用するフォントとして以下のように登録する必要があります。

// Nasu-Regular.ttfとNasu-Bold.ttfファイルはpublic/fonts以下に配置
Fonts.register({
  family: 'Nasu',
  fonts: [
    {
      src: './public/fonts/Nasu-Regular.ttf',
    },
    {
      src: './public/fonts/Nasu-Bold.ttf',
      fontWeight: 'bold',
    },
  ],
})

しかし, これだと以下の画像のようにUnknown font formatというエラーメッセージがコンソールに表示されてしまいます。
コンソールエラー画像

そのため, このエラーに関連する情報を調査したところ, フォント登録をする際にsrcにファイルのパスを指定するのではなく, ファイルを変数としてimportして指定する方法がありました。
上記処理をその方法に書き換えると以下のようになります。

import nasuRegular from './public/fonts/Nasu-Regular.ttf'
import nasuBold from './public/fonts/Nasu-Bold.ttf'

Fonts.register({
  family: 'Nasu',
  fonts: [
    {
      src: nasuRegular as string,
    },
    {
      src: nasuBold as string,
      fontWeight: 'bold',
    },
  ],
})

これで解決かと思いきや, 今度は以下のようなエラーが出てきました。

エラー2

エラーメッセージにModule parse failedとあるのでフォントファイルのパースに失敗しているようですが, 何故失敗しているのかも不明なため苦心していました。

最後の解決策

答えは以下のIssueに載っていました。
https://github.com/diegomura/react-pdf/issues/680#issuecomment-1122218605

まず, src/types以下にfonts.d.tsファイルを作成し, 以下を記述します。

fonts.d.ts
declare module '*.ttf'

次に, next.config.jsを以下のように編集します。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // ...
  webpack: (config) => {
    config.module.rules.push({
      test: /\.ttf$/i,
      type: "asset/resource",
    });
    return config;
  },
  // ...
}

module.exports = nextConfig;

これでreact-pdfで正常にNasuフォントで日本語出力ができるようになります。

参考

https://zenn.dev/furai_mountain/articles/5195f0820ea382

Discussion