Next.jsでサクッとOGP設定やってみた!

2024/12/18に公開

ちょっと株式会社のKindBurgerです!
本記事ではNext.jsの機能を使って、お手軽にOGP設定する実装を紹介します!

やってみたこと🐧

架空のサイト「ペンギンブログ」にて、2つのOGP設定をやってみました!

◆ 汎用的なOGP

トップページやカテゴリページなど、どの画面でも共通して使用できるOGP画像を設定

https://penguin-ogp-work.vercel.app/

◆ 記事詳細で使える動的なOGP

記事ごとの画像やタイトルを組み込んだOGP画像を生成

https://penguin-ogp-work.vercel.app/articles/uj8ls1kaym

https://penguin-ogp-work.vercel.app/articles/yxpqptwmm0

技術的なはなし

◆ 静的画像を用いたOGP

汎用的なOGPでは静的な画像を用意し、各ページに対して共通のOGP情報を設定しました。
Rootのpage.tsxにてStatic Metadataを記述することで、簡単にOGPタグを設定できます。

https://nextjs.org/docs/14/app/building-your-application/optimizing/metadata#static-metadata

project-root/
├── public/
│   └── ogp/
│       └── thumbnail.png // 🌟 静的画像
└── src/
    └── app/
        └── page.tsx // 🌟 Static Metadataの設定
✏️ コード例
src/app/page.tsx
import ArticleList from "./_components/ArticleList";
import styles from "./page.module.css";

// 🌟 Static Metadata
export const metadata = {
  openGraph: {
    title: "ペンギンブログ",
    description:
      "ペンギンブログは、世界中のペンギンの生態、特徴、驚くべき行動を紹介するブログです。ペンギン好きにはたまらない情報が満載!",
    images: [{
      url: "/ogp/thumbnail.png", // 🌟 静的画像の指定
      width: 1200,
      height: 630
    }],
  },
};

export default function Home() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>ペンギンブログ</h1>
      <ArticleList />
    </div>
  );
}

ローカルでの確認

ローカルでは開発者ツールを用いて<head>タグにOGP情報が出力されていることを確認できます。

<meta property="og:title" content="ペンギンブログ">
<meta property="og:description" content="ペンギンブログは、世界中のペンギンの生態、特徴、驚くべき行動を紹介するブログです。ペンギン好きにはたまらない情報が満載!">
<meta property="og:image" content="http://localhost:3000/ogp/thumbnail.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">

デプロイ後の確認

本記事ではVercelにデプロイしたのち、OGPデバッガーを使って各SNSでどのように表示されるか確認しています。

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

◆ 動的データを用いたOGP

記事ごとのOGPはリモートコンテンツからデータ取得し動的に生成しています。

本記事ではopengraph-image.tsxgenerateMetadataの組み合わせで動的にOGP設定してみます。

project-root/
└── src/
    └── app/
        └── articles/
            └── [id]/
                ├── opengraph-image.tsx // 🌟 コードから画像生成
                └── page.tsx // 🌟 generateMetadataの設定

opengraph-image.tsxによるOGP画像生成

Next.jsではopengraph-image.tsxを使用してコードからOGP画像を生成できます。
https://nextjs.org/docs/14/app/api-reference/file-conventions/metadata/opengraph-image

本記事では記事タイトルとサムネ画像を取得し、ImageResponseを返却することでOGP画像を生成しました。

✏️ コード例
import { ImageResponse } from "next/og";

import { getArticleDetail } from "@/app/_libs/microcms/services";

export const runtime = "edge";

export const size = {
  width: 1200,
  height: 630,
};
export const contentType = "image/png";

export default async function Image({ params }: { params: { id: string } }) {
  // 🌟 リモートコンテンツを取得
  const article = await getArticleDetail(params.id);

  // 🌟 ImageResponseを返却
  return new ImageResponse(
    (
      <div
        style={{
          background: "#8bd0dd",
          width: "100%",
          height: "100%",
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <div
          style={{
            display: "flex",
            width: 200,
            height: 200,
          }}
        >
          <img
            // 🌟 リモートコンテンツのサムネイル画像を埋め込み
            src={article.thumbnail.url}
            alt=""
            style={{
              width: "100%",
              height: "100%",
              objectFit: "contain",
            }}
          />
        </div>
        <p
          style={{
            fontSize: 32,
            marginTop: 24,
          }}
        >
          {/* 🌟 リモートコンテンツのタイトルを埋め込み */}
          {article.title}
        </p>
      </div>
    ),
    {
      ...size,
    },
  );
}

generateMetadataによるOGP設定

generateMetadataを用いて、動的に記事ごとのOGP情報を設定します。

https://nextjs.org/docs/14/app/api-reference/functions/generate-metadata

本記事では記事タイトルと概要を取得し、generateMetadataにてog:title og:descriptionを設定しています。

✏️ コード例
import { Metadata } from "next";

import ArticleDetail from "@/app/_components/ArticleDetail";
import { getArticleDetail } from "@/app/_libs/microcms/services";

import styles from "./page.module.css";

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  // 🌟 リモートコンテンツを取得
  const article = await getArticleDetail(params.id);

  return {
    // 🌟 リモートコンテンツのタイトルとディスクリプションを設定
    openGraph: {
      title: article.title,
      description: article.description,
    },
  };
}

interface Props {
  params: {
    id: string;
  };
}

export default async function ArticleDetailPage({ params }: Props) {
  const article = await getArticleDetail(params.id);

  return (
    <div className={styles.container}>
      <ArticleDetail article={article} />
    </div>
  );
}

確認方法

動的データを用いたOGPであっても開発者ツールによるローカル確認とOGPデバッガーによる確認が可能です。

ふりかえり

Next.jsのStatic MetadatagenerateMetadataを使って、汎用的なOGPと動的なOGPの両方をお手軽に実装してみました。

特にリモートコンテンツのデータを用いた動的な生成は、記事ごとに最適なOGPを提供できるので、SNSでのシェア時に視覚的な魅力が高まります!

ぜひ、みなさんもNext.jsでOGP設定を試してみてください🐧✨

chot Inc. tech blog

Discussion