📝

Nextraで動的OGP画像生成

2024/07/07に公開

したこと

Nextraを使っているときに、動的にOGP画像を生成してOGP画像として設定できたので記事に残しておきます。
レポジトリと実際に公開したサイトを載せておきます。

https://github.com/hamao0820/nextra-ogp-sample

https://nextra-ogp-sample.vercel.app/

TL;DR

theme.config.jsxheadプロパティにmetaタグを追加する。

手順

Nextraを準備する

まず、以下のページの手順通りにプロジェクトを作ります。

https://nextra.site/docs/docs-theme/start

その後、いくつかのMDXファイルをpagesディレクトリに直下につくります。

.
├── node_modules
├── next.config.js
├── package-lock.json
├── package.json
├── pages
│   ├── apple.mdx
│   ├── banana.mdx
│   └── index.mdx
└── theme.config.jsx

OGP画像を生成する

以下の記事の通りにOGP画像を生成します。OGPの設定を飛ばして、動的な画像生成までできるようにしてください。
ogp.jsxの場所は以下のファイルと同様です。

https://zenn.dev/yyykms123/articles/2022-12-24-vercel-ogimage-generation

pages/api/ogp.jsx
pages/api/ogp.jsx
import { ImageResponse } from "@vercel/og";

export const config = {
  runtime: "edge",
};

export default function (req) {
  const { searchParams } = new URL(req.url);
  const hasTitle = searchParams.has("title");
  const title = hasTitle
    ? searchParams.get("title")?.slice(0, 100)
    : "My default title";

  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 128,
          background: "white",
          width: "100%",
          height: "100%",
          display: "flex",
          textAlign: "center",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        {title}
      </div>
    ),
    {
      width: 1200,
      height: 600,
    }
  );
}

deployする

次の作業で実際のurlがあった方が便利なので、一旦vercelにdeployしておきます。
その際、ついでにapi/ogpで画像が表示されるかを試してみましょう。

https://nextra-ogp-sample.vercel.app/api/ogp?title=動的OGP にアクセスすると以下の画像が表示されます。

metaタグに追加

theme.config.jsxheadermetaタグを追加することでOGP画像を設定できます。
useConfigを使ってtitleを取得して、クエリとして渡します。

theme.config.jsx
theme.config.jsx
+import { useConfig } from "nextra-theme-docs";

export default {
  logo: <span>My Nextra Documentation</span>,
  project: {
    link: "https://github.com/shuding/nextra",
  },
-  // ... other theme options
+  head: () => {
+    const { title } = useConfig();
+    return (
+      <>
+        <meta
+          property="og:image"
+          content={`https://nextra-ogp-sample.vercel.app/api/ogp?title=${title}`}
+        />
+      </>
+    );
+  },
+  useNextSeoProps: () => ({
+    defaultTitle: "nextra-ogp-sample",
+    titleTemplate: "nextra-ogp-sample",
+    description: "nextra-ogp-sample",
+    twitter: {
+      handle: "@hamao_0820",
+      site: "@hamao_0820",
+      cardType: "summary_large_image",
+    },
+    openGraph: {
+      url: "https://nextra-ogp-sample.vercel.app",
+      description: "nextra-ogp-sample",
+    },
+  }),
};

もう一度deployして確かめる

もう一度デプロイして、動的に生成されたOGP画像が表示されているか確かめてみます。
このサイトで調べることができます。

https://rakko.tools/tools/9/

ちゃんと表示されました🎊
これで完成です。

theme.config.jsxtwitterプロパティは必須ではないですが、設定しておくとTwitterでもこのようにOGP画像が表示されます。

https://x.com/hamao_0820/status/1809786043551580317

LINEでもちゃんと表示されました。

Discussion