Edited at

Vue.jsで静的にOGP対応する

More than 1 year has passed since last update.

とりあえず方法が知りたい人は、これが結論まで飛んでください。


OGPの基礎知識

OGPはサイトをSNSでシェアする時に出てくるサムネイルと概要を設定する機能のことです。

HTMLのヘッダー内にmetaタグを記述することで実現できます。

最低限必要なmetaタグは以下の通りです。

<meta property="og:title" content="The Rock" />

<meta property="og:type" content="video.movie" />
<meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
<meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" />

参照:ogp.me

ここで注意するのは、サイトのurlもimageのurlもパスではなくURLで指定するということです。他の人が他のサイトに埋め込むコンテンツなのだから、そういうものなのでしょう。

サイトがOGPに対応しているかどうかを調べるには、以下のページが有用です。

https://cards-dev.twitter.com/validator

https://developers.facebook.com/tools/debug/sharing/


vue.jsにOGPを追加する際の問題点

まず、vue.jsのデフォルトの機能では<head>を書き換える機能がありません。

これについてはvue-headというプラグインでなんとかなりますが、根本的な問題としてOGPを読みにくる様々なサーバのbotは、そのほとんどがjavascriptを展開しないという問題があります。

つまり、いくら動的に<head>を書き換えてもOGP対応という点においては意味がないのです。


どのような対応法があるか?


SSR ( Server Side Rendering ) をする

アクセスが来た時にサーバの側でページをレンダリングしてからユーザに返すという方法です。

しかし、動的にコンテンツを生成できるサーバを用意することが必要で、静的なホスティングサーバにデプロイする予定の時は使えません。


プリレンダリングする

事前にレンダリングしたページを用意するという方法です。SSRを使う方法と比べるとサーバを用意する必要がなくお手軽です。

参照:Vue.jsのプリレンダリングで手軽なOGP対応

しかし、これをするとそもそもSPAではなくなってしまうという点があります。Vue.jsを効率的に静的なウェブサイトを開発するものというだけの意味で使っているのならばこれを採用してもいいでしょうが、SPAの利点を活用したいのならば採用は難しいと思われます。

これらの点を加味して、私は以下の方法を採用しました。


テンプレート内に直接OGPを書き込む

最初に問題点を挙げておくと、OGPの内容を動的に変更することはできず、全てのページで同じ内容のOGPになります。でも、トップページのみ正確にOGPに対応していればいいや、という考えのもとこれを採用しました。

この方法でも一応、トップページ以外のURLをシェアされてもちゃんとシェアされたURLに飛ぶことができます。タイトルやdescriptionはトップページと同じものになりますが。

以下、方法です。特殊なプラグインなどは必要ありません。


これが結論

まず、プロジェクトのルートディレクトリを開きます。そこにindex.htmlというテンプレートファイルがあるので、その<head>内にOGPに必要なmetaタグを入れるだけです。