Netlify ではじめての OGP on SPA

どうも。Cocoda!のエンジニアのいがりです。
Cocoda!の一部がログインせずに見られる仕様になり、OGPを表示させたくなりました。はじめてのOGP対応だったので覚え書きとして残します。

## 環境
React.jsによるSPAをNetlifyでホスティングしています。

## 要件
TwitterでシェアしたときにOGPがページごとに動的に変えて表示されるようにしたい！

## OGPとは
Open Graph Protocolの略。
SNSでシェアしたときに、リンク先の情報が表示されるよく見るアレです。
![スクリーンショット 2019-02-19 2.39.04.png](https://qiita-image-store.s3.amazonaws.com/0/143036/5d558e68-d10e-9830-42fe-f6bde30381b2.png)

OGPを設定していないとシェアしたときに下のような簡素な印象になります。 (postdさん、ごめんなさい。ちょうどシェアしたときにうまく言ってなかったようなので使わせていただきます。めちゃめちゃ好きなメディアです。)
![スクリーンショット 2019-02-19 2.42.04.png](https://qiita-image-store.s3.amazonaws.com/0/143036/740e663b-80e8-4d87-8a87-b151a0105177.png)

シェアされる、あるいはシェアしてほしいページはOGPを設定したいですよね。

## OGPの設定の仕方
OGPの設定はmetaタグによって可能です。
![スクリーンショット 2019-02-19 2.39.04.png](https://qiita-image-store.s3.amazonaws.com/0/143036/5d558e68-d10e-9830-42fe-f6bde30381b2.png)

このOGPは以下のタグによって表示されています。ディベロッパーツールから確認できます。

```html
<head>
  <meta property="og:url" content="https://news.google.com">
  <meta property="og:title" content="Google ニュース">
  <meta property="og:image" content="https://lh3.googleuserc...">
  <meta property="og:description" content="Google ニュースが世界中のニュース提供元から集約した広範囲にわたる最新情報">
</head>
```

## OGP生成の課題
jsからmetaタグを動的に書き換えれば一見すぐOGP表示できそうですが、そんなに甘くなかった。。。😢

TwitterやFacebookクライアントはjsを解釈してくれないので、シェアしたときに、動的に書き換える前の、取得した素のhtmlに書いてあるmetaタグのみしか見てくれません。


つまり、 **サーバーから返した静的なファイルのOGPを読み込ませる必要があります。**

## 解決策
調べたところ解決策が２つありました。

- SSR(サーバーサイドレンダリング)
- prerender

### SSR
> (元々ブラウザ上でしか動かなかった)JavaScriptをサーバー内部で実行して、HTMLを生成すること

by https://medium.com/@sundaycrafts/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E4%BD%93%E9%A8%93%E3%82%92%E5%90%91%E4%B8%8A%E3%81%95%E3%81%9B%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%B5%E3%82%A4%E3%83%89%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0javascript-%E6%AD%B4%E5%8F%B2%E3%81%A8%E5%88%A9%E7%82%B9-df68cd7cd991

ここで詳しく述べるのは控えますが、フロントエンドが複雑になりそうだなーという印象がありました。

### prerender
prerender とは、あらかじめレンダリングしたファイルを読み込むことです👀。これによってjsによって動的なアプリケーションであっても、SSRせずに静的なファイルをクライアントに返すことができます。

サイトのホスティングに使用している Netlify ではbeta版で [prerenderのサポートをしています](https://www.netlify.com/docs/prerendering/)。

> Our built-in prerendering service will cache prerendered pages for between 24 and 48 hours; this is not adjustable.
当社の組み込みの事前レンダリングサービスは、事前レンダリングされたページを24〜48時間キャッシュします。 これは調整できません。

なるほど。

簡単に設定できそうだったのでとりあえずNetlifyのprerender機能を試してみることにしました。（しかも無料）

## Prerenderまでの手順
　1. [React Helmet](https://github.com/nfl/react-helmet) を使って動的にmetaタグを書き換える
![スクリーンショット 2019-02-19 3.37.06.png](https://qiita-image-store.s3.amazonaws.com/0/143036/752c5abe-3000-ca39-5b24-531680e0815a.png)


　2. NetlifyのSettingsタブのPrerenderingセクションに移動
![スクリーンショット 2019-02-19 3.22.40.png](https://qiita-image-store.s3.amazonaws.com/0/143036/84e6263a-5d97-7106-a527-901b4f309819.png)

　3. Enable Prerenderingにチェックを入れる
![スクリーンショット 2019-02-19 3.24.14.png](https://qiita-image-store.s3.amazonaws.com/0/143036/78f5201d-752d-094b-b4fd-80e89bc669fd.png)

　4. robots.txtにOGPを表示したいサイトのクロールを許可する

```
User-agent: Twitterbot  # Twitterは許可する
Allow: /allow           # /allow パスはクロールを許可する
```

　5. fetch as googleする
robots.txtはキャッシュされるので、 [fetch as google](https://www.google.com/webmasters/tools/googlebot-fetch?hl=ja) からGoogleに再読込してもらいます。
![スクリーンショット 2019-02-19 3.42.51.png](https://qiita-image-store.s3.amazonaws.com/0/143036/f7ea1893-46b3-d2e0-813c-296d2a0e0381.png)


　5. OGP表示の確認

TwitterでのOGP表示のプレビューができる [Card validator](https://cards-dev.twitter.com/validator) で確認してみます。
![スクリーンショット 2019-02-19 3.29.56.png](https://qiita-image-store.s3.amazonaws.com/0/143036/730585ba-32ed-afaa-0c20-fecf0ecedc36.png)

**！！！！以上！！！！**
爆速でOGP設定できました。すごいぞNetlify。

## まとめ
超簡単にOGP設定できちゃいました。
SPAでのOGP生成で悩んでいる人に届くと良いな。