🔠

【Next.js / App Router】 opengraph-image.tsxのOG画像内フォントの変更方法

2024/07/21に公開

こんにちは!@Ryo54388667です!☺️

普段は都内でエンジニアとして業務をしてます!
主にTypeScriptやNext.jsといった技術を触っています。

今回は、Next.jsのApp Routerを使用してOG画像内のフォントを変更する方法について紹介します。

📌 Next.js(App Router)のOG画像の設定方法

まず、OG画像の設定方法について説明します。

appディレクトリ配下のセグメントごとにopengraph-image.tsxtwitter-image.tsxというファイルを作成でき、これらはOG画像として配信されます。
Next.js(App Router)では、next/ogライブラリを使用して、オリジナルのOG画像を生成できます!めちゃくちゃ便利です!

https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image

これらを設定したときに、フォントの変更が意図どおりにいかず苦労したので、備忘録替わりに紹介していきます!

📌 フォントを変更する方法

任意のもので全く構わないのですが、今回は日本語フォント「Kosugi Maru」を使用します。

まず結論

① フォントのデータをプロジェクトに格納

まず、Googleフォントから必要なフォントをダウンロードします。以下のリンクからフォントを取得できます!

Googleフォント

ダウンロードしたフォントファイル(例:KosugiMaru-Regular.ttf)をプロジェクトの任意の場所に格納します。この例では、publicディレクトリに格納します。

② 実装

次に、ダウンロードしたフォントデータを使用してOG画像を生成するためのコードを実装します。

// opengraph-image.tsx
import { ImageResponse } from 'next/og'
import fs from 'fs'
import path from 'path'

export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

export default async function Image() {
  // ✅ 直接ファイルを読み込む
  const fontData = await fs.readFileSync(path.join(process.cwd(), 'public/KosugiMaru-Regular.ttf'))
  return new ImageResponse(
    (
      <div style={{ fontFamily: 'Kosugi Maru' }}>
        <div>
          日本語: テスト てすと
        </div>
      </div>
    ),
    {
      ...size,
      // ✅ こちらにフォントのデータを設定
      fonts: [
        {
          name: 'Kosugi Maru',
          data: fontData,
        }
      ]
    }
  )
}

実行結果

(※ フォントが反映しなかった時の画像は失敗例のセクションにあります)

結局、ライブラリの使用を断念し、ローカルに保存したフォントデータを直接読み込む方法で実現しました。ただ、もしかすると、データのサイズが大きい場合、Edgeランタイムでは動作しない可能性があります。

試行錯誤したので、うまくいかなかった方法も合わせて書いておきます。

❌ うまくいかなかった例①: next/font/google を利用

next/font/googleライブラリを使用してフォントを適用しようとした例を紹介します。この方法ではうまくいきませんでした😇プロジェクトページでは反映されるんですけど。。

// opengraph-image.tsx
import { ImageResponse } from 'next/og'
import { Kosugi_Maru } from 'next/font/google'

const KosugiMaru = Kosugi_Maru({ weight: "400", subsets: ["latin"] });

export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

export default async function Image() {
  return new ImageResponse(
    (
      <div className={KosugiMaru.className} >
        <div>
          日本語: テスト てすと
        </div>
      </div>
    ),
    {
      ...size
    }
  )
}

実行結果

この方法では、フォントが反映されませんでした。
satoripuppeteerが影響しているのですかね。。🤔

❌うまくいかなかった例② : next/font/local を利用

続いて、next/font/localライブラリを使用してフォントを適用しようとした例です。この方法でもうまくいきませんでした。。😇

// opengraph-image.tsx
import { ImageResponse } from 'next/og'
import localFont from 'next/font/local'

const KosugiMaru = localFont({ src: '../../../public/KosugiMaru-Regular.ttf' })

export const size = {
  width: 1200,
  height: 630,
}

export const contentType = 'image/png'

export default async function Image() {
  return new ImageResponse(
    (
      <div className={KosugiMaru.className} >
        <div>
          日本語: テスト てすと
        </div>
      </div>
    ),
    {
      ...size
    }
  )
}

実行結果

この方法でも、フォントが反映されませんでした。

📌 最後に

Next.jsのApp Routerを使用してOG画像内のフォントを変更する方法について紹介しました。端的にまとめると、ローカルにフォントデータを保存して直接読み込んで、フォントを反映させるように実装しました。

もし他により良い方法があれば、ぜひ教えてください〜🙇‍♂️

最後まで読んでいただきありがとうございます!

ブログも書いてます〜
https://ryotablog.jp/blogs/my-seo-todo-list

気ままにつぶやいているので、気軽にフォローをお願いします!🥺
https://x.com/Ryo54388667/status/1809370602362581053

Discussion