執筆時点で、このブログはastro-paper
というAstroテンプレートをカスタマイズして作成しています。astro-paper
には、ブログ記事をSNSでシェアしたときに表示されるOGP画像の生成機能も含まれています。
OGP画像はsatori
を利用して生成されています。satori
はVercelが提供している、HTMLを画像に変換するためのツールです。
astro-paper
は非常に便利なテンプレートですが、デフォルトでは日本語非対応のIBM Plex Mono
フォントが指定されているため、日本語テキストを含むOGP画像が正しく表示されません。
本記事では、この問題を解決し、satoriで日本語フォントを適切に使用する方法を説明します。
日本語の文字化け
初期設定のIBM Plex Mono
のまま、日本語を含むテキストをOGP画像に変換すると、日本語に対応していないため、文字化けが発生します。
先日ポストした「GitHub ActionsからCloudflare pagesにDirect Uploadする」という記事のOGP画像です:
(こちらのサイトでURLを入力してOGP画像を確認できます)
日本語文字が文字化けしているのがわかります。
ちなみに、ローカルの環境に日本語フォントがインストールされている場合、フォールバックフォントが使われるため、日本語が文字化けしないことがあるので注意が必要です。自分のmacOSでビルドすると、IBM Plex Mono
を使っていても、日本語が文字化けしませんでした。
そのため、CI環境でビルドしたOGP画像が文字化けしているかを確認することが重要です。
日本語フォントファイルを探す
今回は日本語対応フォントのNoto Sans Japanese
を使います。
Satoriの設定は簡単で、フォントファイルをロードし、Satoriのコンフィグに追加するだけです。フォントファイルは、.ttf
/ .otf
/ .woff
形式に対応しているようです(執筆時点で.woff2
には未対応、公式のREADME参照)。
astro-paper
におけるSatoriの設定箇所はこちらです。Regular
とBold
の2種類のフォントファイルが必要になります。
ほとんどのフォントファイルはGoogle Fontsからダウンロードできますが、今回はCDNでホストされているフォントファイルを見つけたので、そちらを使います。CDNを利用することで、ファイルをコードに追加する必要がなくなります(astro-paper
もデフォルトでCDNからフォントファイルを取得しています)。
CDNはどこでも良いですが、jsDelivr
を使いました。
“noto sans jp”で検索すると、いくつかパッケージが表示されます:
パッケージによっては、細かくフォントファイルが分割されている場合があります。分割されている場合、読み込みに手間がかかるので、利用は避けて別のパッケージを探してみることをオススメします。今回は@openfonts/noto-sans-jp_japanese
を利用しました。
Satoriの設定
CDNパッケージのページで必要なフォントファイルと対応するURLを確認し、Satoriのconfigに追加します。
どのファイルをRegularとBoldとして使うかは、ローカルでOG画像を生成して確認しながら決めると良いでしょう。@openfonts/noto-sans-jp_japanese
の場合、ファイル名にフォントのweight(100、200といった数字で、数字が大きいほど太字)が含まれているので、参考にして選びます。
今回は以下のように設定しました:
- Regular:
{長いので省略}/files/noto-sans-jp-japanese-300.woff
- Bold:
{長いので省略}/files/noto-sans-jp-japanese-500.woff
satori
のコンフィグファイルsrc/utils/generateOgImages.tsx
を以下のように編集します:
@@ -7,13 +7,13 @@
const fetchFonts = async () => {
// Regular Font
const fontFileRegular = await fetch(
- "https://www.1001fonts.com/download/font/ibm-plex-mono.regular.ttf"
+ "https://cdn.jsdelivr.net/npm/@openfonts/[email protected]/files/noto-sans-jp-japanese-300.woff"
);
const fontRegular: ArrayBuffer = await fontFileRegular.arrayBuffer();
// Bold Font
const fontFileBold = await fetch(
- "https://www.1001fonts.com/download/font/ibm-plex-mono.bold.ttf"
+ "https://cdn.jsdelivr.net/npm/@openfonts/[email protected]/files/noto-sans-jp-japanese-500.woff"
);
const fontBold: ArrayBuffer = await fontFileBold.arrayBuffer();
@@ -28,13 +28,13 @@
embedFont: true,
fonts: [
{
- name: "IBM Plex Mono",
+ name: "NotoSansJP",
data: fontRegular,
weight: 400,
style: "normal",
},
{
- name: "IBM Plex Mono",
+ name: "NotoSansJP",
data: fontBold,
weight: 600,
style: "normal",
実際にデプロイして確認します。修正後のOGP画像:
文字化けが解消され、日本語が正しく表示されました。
まとめ
satori
を使ってOGP画像を生成する際、日本語を含むテキストが文字化けする問題を解決するために、日本語フォントを使う方法について説明しました。
設定自体は簡単ですが、CIとローカルの差分や、日本語対応のフォントを見つけたりするのに時間がかかったので、記録として残しておきます。