Vue.jsでSPAを構成した際、TwitterなどのOGPが上手く表示されなかったので、対処した。

SPAとは?→シングルページアプリケーション

この記事で扱っているSPAとは、シングルページアプリケーションを指す。
SPAについては少し以下の記事で触れたが、詳細は他のサイトの方が詳しいと思う。

OGPとは?→Webページのリンクを表示する仕組み

OGPとはOpen Graph Protocolの略で、TwitterとかFacebookとかでリンクがいい感じに表示されるアレに使われているプロトコルのこと。

↓これ。

webサイトをいちから作る際、OGP対応していないと、Twitterとかでリンクを貼り付けても画像や説明文は表示されない。
そこらへんはTwitter側でなんとかしてくれるわけではなく、サイト作成者側が適切にOGP設定を行う必要がある。

SPAの場合はOGP設定にひと工夫必要

OGPは、具体的にはHTMLにmetaタグを設定することで対応できる。
例えば、以下のようなmetaタグを<head>要素内に設定する。

上記は私が作成したサイトの実装例になるが、他のサイトを調べると、head要素にprefix属性を適切に設定する必要があるようだ。
私は設定していなかったが、とりあえずTwitterあたりでは問題なく動いているように見える。
まあ、正しい対応ではないと思う。

このOGP設定だが、SPAの場合はひと工夫必要になる。
理由は、OGPによってリンクを作成する際、JavaScriptが動かないケースがあるため。

OGPによってリンクを表示する際、クローラーと呼ばれるプログラムによって、リンク先のページをスキャンする。
スキャン結果に従ってリンクを表示するのだが、TwitterやFacebookのクローラーはJavaScriptを実行してくれないらしい。
よって、JavaScriptによってmetaタグを生成しても、リンクには反映されない。
SPAでOGP設定を適切に行う場合はここら辺の対処が必要。

今回は特定条件時のみ静的ページを返すように実装

今回の結論、解決策になる。

調べてみると、(Vue.jsを用いた)SPAでのOGP設定については色々対応策があった。
いくつか参考にさせていただいたページを挙げておく。

上記のページの方法はページ内にも書かれている通り、全てのページで同じ内容のOGPになってしまう。
今回はそれぞれのページで異なるOGPを設定したいため、同じ方法はとらなかった。

上記のページは詳しく書いてあり、参考になりそうだったが、Firebaseを使ってない、使ったことがないため今回は同じ方法をとれなかった。

最終的には以下のページの方法を真似させていただいた。

上のページの方法は、TwitterやFacebookなど特定のクローラーに対してのみOGP対応用のテンプレートを返すというものになっている。
アプローチとしては一番最初に挙げたページと同じだが、こちらはクローラー検出用にControllerを作成して、テンプレートの出し分けをしている。

比較的容易に実装でき、ページごとに異なるOGP設定ができそうだったため、こちらの方法を採用した。

この方法の課題としては、OGP対応用のテンプレートを返す相手をピンポイントで指定する必要があるため、明示的に指定したクローラー以外に対しては対応できない点がある。
また、OGP対応用のControllerを新規に作成する必要があり、Controllerが単純に1個増える。

なお、各サービスのクローラーの情報は以下のサイトを参考にさせていただいた。

雑記

Twitterでのリンク表示内容確認には以下の公式のサイトが便利。