2021-08-22

Next.jsで動的OGPを生成しメタ情報を出し分けてみた

blogimg

TwitterやLINEなどでリンクを貼った時、OGPの設定をしていればタイトル、画像、概要などをカードのような形で表示できるようになります。

逆に設定していないとせっかくリンクを共有しても目に止まらない可能性が高いです。OGPが動的というのは、例えばブログ記事のidによってタイトル、画像、概要を出し分けるということです。

ということでNext.jsで作成したサイトで動的OGPを作成する方法についてのメモです。

コンポーネント作る

まずはOGP用のコンポーネントをnext/headを使って作っていきます。

こちらのサイトを参考にさせていただきました。

import Head from 'next/head';

const Seo = ({ pageTitle, pageDescription, pagePath, pageImg, pageImgWidth, pageImgHeight }) => {
  const defaultTitle = 'サンプル';
  const defaultDescription = 'サンプルディスクリプション';
  const defautlImg = 'https://sample.jp/sample-logo.png';

  const title = pageTitle ? `${pageTitle} | ${defaultTitle}` : defaultTitle;
  const description = pageDescription ? pageDescription : defaultDescription;
  const url = pagePath;
  const imgUrl = pageImg ? pageImg : defautlImg;
  const imgWidth = pageImgWidth ? pageImgWidth : 1200;
  const imgHeight = pageImgHeight ? pageImgHeight : 630;

  return (
    <Head>
      <title>{title}</title>
      <meta name="viewport" content="width=device-width,initial-scale=1.0" />
      <meta name="description" content={description} />
      <meta property="og:url" content={url} />
      <meta property="og:title" content={title} />
      <meta property="og:site_name" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:type" content="website" />
      <meta property="og:image" content={imgUrl} />
      <meta property="og:image:width" content={String(imgWidth)} />
      <meta property="og:image:height" content={String(imgHeight)} />
      <link rel="preconnect" href="https://fonts.gstatic.com" />
      <link
        href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&amp;display=swap"
        rel="stylesheet"
      />
      <link rel="canonical" href={url} />
    </Head>
  );
};

export default Seo;

こちらをトップページに埋め込むととりあえずはOGPが設定された状態になります。

これをブログ記事によって変えたいのであれば、propsに値を渡すことで可能になります。

import Layout from '../components/Layout';
import Seo from '../components/SeoOgp';

export default function Home({ blog, totalCount }) {
  return (
    <Layout title="Home">
      <Seo />
    </Layout>
  );
}

このように設定します。

例えば、ブログ記事の情報に変えたいなら、blogs/[id].jsなどのファイルで、

import Layout from '../../components/Layout';
import Seo from '../../components/SeoOgp';

export default function BlogId({ blog }) {
  return (
    <Layout title="blog">
      <Seo
        pageTitle={blog.title}
        pageDescription={blog.body}
        pageImg={blog.image.url}
        pageImgWidth={1280}
        pageImgHeight={960}
      />
    </Layout>
  );
}

などとします。