あるWebサービスの開発メモ・next.js で SSR を実行して OGP用の meta タグを SNS サイトなどに送出する

- [あるWebサービスの開発メモ・目次ページに戻る](https://qiita.com/ishi32/items/152a1ecf7eeee7a8fb57)

## やりたいこと

ここでやりたいことは、OGP 用の meta タグを送出することで、SNS サイトなどで見栄え良くリンク先として表示してもらいたい、ということです。具体的には以下のイメージになります

![スクリーンショット 2022-11-10 14.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/c0b03f34-15ec-92e5-d53b-6f1c685d565b.png)

イメージファイル (sirokuro.png) のデザインは改善の余地ありですが、そこは後回しにします

## 方式検討

はじめてやることなので、思考錯誤しながらの方式検討です

### OGP 用の meta タグを用意する

#### 情報収集

- [独り言形式で綴る「OGP & SSR」](https://zenn.dev/yumemi_inc/articles/0098b3e850676f)
結局、このページが一番わかりやすくって、なぜ SSR しないと OGP が有効になってくれないかを教えてくれている
- [2022年版：OGPの正しい設定方法まとめ](https://webdesign-trends.net/entry/12993#OGP)
- [Next.jsでOGP・metaタグを設定する方法](https://qiita.com/TK-C/items/cd34d0f6d4b001053443)
- [【Next.js × Vercel】OGP画像を動的生成してみた](https://ji23-dev.com/blogs/nextjs-ogp)
- [[Vercel] ウェブサイトのOGP情報を取得する Serverless Functions を作成する](https://kotsukotsu.work/tech/2020-09-13-vercel-ウェブサイトのogp情報を取得する-serverless-functions-を作成する/)
- [テキスト内のハッシュタグやURLをリンクにする](https://omkz.net/text-url-link/)

#### 動作確認用にツールとか

- [(twitter) Card validator](https://cards-dev.twitter.com/validator)
  - [「Unable to render Card preview」と出るのは仕様らしい](https://www.naporitansushi.com/unable-to-render-card-preview/)
- [OGP確認](https://rakko.tools/tools/9/)
大変ありがたいツールですがハマりました。どうしても「設定情報が取得出来ませんでした。URLをご確認ください。」と表示されてしまい、コードを見直したり、ブラウザに返却されたコードを見直したり、サーバサイドに生成された HTML ファイルを見直したりしていたのですが、新しいブラウザタブからアクセスしたら

![スクリーンショット 2022-11-10 19.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539175/13d394c8-407d-dbef-99e9-f3053d8d00dc.png)

- [OGP画像シミュレータ](https://ogimage.tsmallfield.com)

#### 実際にやったこと

nextjs の場合は Head コンポーネントを使って meta タグを出力します。今まで当サイトでは Head コンポーネント の 中には title タグしかなかったので、各 ``` ./pages/hoge.tsx ``` にて

```
<Head>
  <title>シロクロつける</title>
</Head>
``` 

という感じで定義していました。OGP の meta タグは複数定義する必要があるので、以下の Seo コンポーネントを追加しました

``` ./components/Seo.tsx ```

```
import { FC } from "react";
import Head from "next/head";

interface MetaData {
  pageTitle?: string;
}

export const Seo: FC<MetaData> = ({ pageTitle }) => {
  return (
    <Head>
      <title>{pageTitle}</title>
      <meta name="description" content={pageTitle} />
      <meta property="og:url" content="https://www.sirokuro.site" />
      <meta property="og:title" content="シロクロサイト" />
      <meta property="og:site_name" content="シロクロサイト" />
      <meta
        property="og:description"
        content="モノ・コトにシロクロつけるサイト"
      />
      <meta property="og:type" content="website" />
      <meta
        property="og:image"
        content="https://www.sirokuro.site/sirokuro.png"
      />
      <meta property="og:image:width" content={String(1600)} />
      <meta property="og:image:height" content={String(220)} />
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:site" content="@sirokuro_site" />
    </Head>
  );
};
````

各ページでは以下の感じで Seo コンポーネントを呼び出します

``` ./pages/index.tsx ```

```
import { Seo } from "../components/Seo";

(snip)

      {/* <Head>
        <title>sirokuroつける</title>
      </Head> */}
      <Seo pageTitle="sirokuroつける" />

(snip)
```

### SSR

[当サイト](https://sirokuro.site) ではこれまで SSR (サーバサイドレンダリング) を実行していませんでした。ということは Google のクローラにページを読んでもらえず、Google のキーワード検索にはヒットしないものと思っていました

これはどうも間違いだったらしく、現在の Google クローラは最新の Chromium レンダリングエンジンを実行しているので Chromeブラウザに表示可能な JavaScript であれば、これをハイドレーションした結果を読んでくれるそうです

しかしながら、OGP 用の meta タグを SNS サイトなどに読み取ってもらうには、静的な html ページが必須になってしまうようです

#### やったこと

続きは明日書きます