目的
URLに応じて、OGPの内容を切り替えたい。けどSSR(サーバーサイドレンダリング)は使わず静的ホスティングでやりたい。
例)
* hoge.com → 英語のOGPを表示
* hoge.com/ja → 日本語のOGPを表示
OGPを切り替えたかったらSSRで行うのが一般的ですが、静的ホスティングでも実現はできなくない。そういう記事がなかったので記録します。シンプルにしたいとか、サーバーの都合とかで静的ホスティングにしたい場合に活用できます。
TL;DR
- MPAでプロジェクトを作成する
- 各htmlファイルに別々にOGPを記入する
- (多言語対応なら)各エントリーポイントで読み込むテンプレートは同一にして、読み込む言語ファイルを動的に変更する
最終構成図
留意点
- 多くのページ(例えばブログの各記事)にOGPを別々に設定する、などには不向きです
- 多言語対応くらいの、運用中に基本増えることがないような量であれば現実的です
参考記事
Vue CLI 3でSPAではなくMPA(複数エントリーポイント)のプロジェクトを作成する
やり方
通常htmlファイルが一つなのがSPAで、Vue.jsの特徴でもありますが、複数のhtmlファイルを用いたMPAも可能です。
OGPを切り替えたいぶんだけhtmlファイルを用意し、それぞれに別々のOGPを記入したMPAプロジェクトを作成することで実現できます。
参考記事にMPAのセットアップ方法があり、そこで作成したhtmlファイルに別々のOGPを記入することで、「URL毎にOGPを切り替える」は実現できるので、ここでは割愛させていただきます。
そこから、多言語対応のために、
- テンプレートファイルを一つにする
- URLに応じて言語を切り替える
の2点をするのに必要なセットアップを説明します。
vue-router
複数のURLに対してテンプレートファイルを一つにする場合、vue-routerはhashモードでないといけないです。historyモードだとルーティングがおかしくなってしまいます、、
ファイル構成
私は日本語と英語に対応させたかったので2つ作成しました。中身は後述します。
- 英語用エントリーポイント
- public/index.html
- src/pages/en/main.js
- 日本語用エントリーポイント
- public/ja.html
- src/pages/ja/main.js
- テンプレートファイル(英語日本語共通)
- App.vue
(図ではTypeScriptになっていますがJavaScriptでも同じです)
main.jsの記述
次のように、main.jsを記述します。ポイントは、
* どちらも同じテンプレートApp.vueを読み込む
* Vue.prototype.lang = 'en'
などと言語を指定する
import Vue from 'vue';
import App from '@/App.vue';
Vue.config.productionTip = false;
// set language to english
Vue.prototype.lang = 'en';
new Vue({
render: h => h(App)
}).$mount('#app');
import Vue from 'vue';
import App from '@/App.vue';
Vue.config.productionTip = false;
// set language to japanese
Vue.prototype.lang = 'ja';
new Vue({
render: h => h(App)
}).$mount('#app');
App.vueの記述
プロジェクトをvue-cliで作成したデフォルトのままで大丈夫です。
vue.config.js
次のようにしてエントリーポイント毎にファイルを設定します。
module.exports = {
pages: {
top: {
entry: 'src/pages/en/main.js', // エントリーポイントとなるjs
template: 'public/index.html', // テンプレートのHTML
filename: 'index.html', // build時に出力されるファイル名
title: 'たいとる'
},
ja: {
entry: 'src/pages/ja/main.js',
template: 'public/ja.html',
filename: 'ja.html',
title: 'たいとる'
}
}
};
OGPの記入
index.htmlには英語のOGPを、ja.htmlには日本語のOGPを記入します。
<!-- OGP -->
<meta property="og:url" content="https://hoge.com" />
<meta property="og:type" content="website" />
<meta property="og:title" content="title" />
<meta property="og:description" content="description" />
<meta property="og:site_name" content="title" />
<meta property="og:image" content="https://hoge.com/hoge.png" />
動作確認
ここまででのセットアップで、2つのURLhoge.com/
と hoge.com/ja
どちらもApp.vueのページが表示されるようになったはずです。そうなっていれば、最終構成図の矢印で示された接続は完成しています。twitterシェアデバッガーなどにURLを入力したら、2つのURLで別々のOGPが表示されるはずです。
言語の動的な切り替え
main.js で Vue.prototype.lang='en'
などと設定したことで、テンプレート内のどこでも、Vue.prototype.lang
とすることで今どの言語のページが表示されているかが読み込めるようになります。言語別に表現をjsonファイルなどで用意しておき、Vue.prototype.lang
によって読み込みを変えることで多言語対応が実現できます。
App.vue内でURLを読み取って言語判定することもできますが、main.js内で行うとマウントの前に言語判定できて、またコードもきれいになると思います。
(例)
{
"title": {
"en": "TITLE",
"ja": "たいとる
}
}
<h1>{{ title }}</h1>
<script>
created() {
// langsJsonにlangs.jsonを読み込んでおく
this.title = langJson.title[Vue.prototype.lang]
}
</script>
具体例
こちらの仕組みで多言語対応を行ったサイトがこちらになります。
ユーザーネームチェッカー
課題
- hashモードを利用しないといけないためURLがきれいじゃない、、