Nuxt.js (1.4) を使ったプロダクトをローンチしたので、便利だったモジュール・テクニックなどをまとめます。
Bootstrapを便利に使う
bootstrap 4 を便利に使うために、Bootstrap Vue が存在する。モジュールとしてロードできる仕組みが存在するので、以下の方法で利用が可能です。
yarn add bootstrap
yarn add bootstrap-vue
cssの設定で、CSSをそのまま利用するかを選択できる。 (デフォルトは true
)
module.exports = {
modules: [
['bootstrap-vue/nuxt', { css: false }]
]
}
今回、bootstrap のテーマを変更したいため、 css: false
にして、以下の用に assets を読み込むことにしました。
@import '~bootstrap/scss/bootstrap';
// bootstrap のデザインカスタマイズ
html {
font-size: 14px;
}
// ...
module.exports = {
css: ['@/assets/bootstrap.scss']
}
この方法だと、ファイルサイズがやや大きくなってしまうので、個別に必要なコンポーネントとディレクティブを呼ぶ方法を利用したいのですが、残念ながら Nuxt.js 上では動作しない問題があります。(Issue参照のこと)
よく使うコンポーネントと、諸注意
モーダルダイアログを出したり、消したりする機能を提供する。b-modal
コンポーネントの利用が便利。
単体のチェックボックス、もしくはグループを管理することができる。b-form-checkbox
にはIDを正しく付与しないと、SSRモードでは動作しない(チェックを入れようとしてもチェックが入らない)ので注意。解決策は2つあります。
- IDを正しく付与する:
b-form-checkbox
を利用するときは、id属性を指定する。 (おすすめ) -
b-form-checkbox
を利用するときは、no-ssr
コンポーネントを利用する。
<no-ssr>
<b-form-checkbox v-model="check">Check</b-form-checkbox>
</no-ssr>
この現象は、b-form-radio
コンポーネント利用時にも発生します。
トーストUIの追加
Bootstrap4 には、トーストUIが存在しないため、別のモジュールを利用しました。
@nuxtjs/toast モジュールを利用することで、vue-toasted を簡単に利用することができます。
yarn add @nuxtjs/toast
module.exports = {
modules: [
['@nuxtjs/toast']
],
// toasted のデフォルト挙動設定
toast: {
// 右上にtoastを表示
position: 'top-right',
// 特に指定しなくても5秒で消えるように設定
duration: 5000
}
}
あとは、アプリケーション内では、必要なタイミングで以下を実行するだけで、toastが利用できるようになります。
this.$toast.show('保存しました')
i18n
Nuxt.js 上で i18n を行うには、vue-i18n を利用するのが便利。翻訳データに YAML を利用するには、少し手を加える必要あり。 nuxt.js で vue-i18n を使えるようにする にて知見をまとめています。
ユニバーサルなCookieの利用
Nuxt.js では、サーバサイドでの動作・クライアントサイドの動作が存在するので、Cookieを利用する場合は要注意でした。仮に、asyncData() にて Cookie を利用する場合は、以下のようにヘンテコなコードを書く必要が出てきてしまいます。
<script>
export default {
asyncData ({req}) {
let hoge = null
if (process.server) {
// サーバサイドレンダリングの場合
hoge = req.cookies.hoge
} else {
// クライアントの場合
// document.cookie を parse するなど
}
// ...
}
}
</script>
Cookie情報のparseには、vue-cookieの利用などが、便利ですが、サーバサイドとクライアントサイドで条件分岐してしまう面倒さは避けられません。
そこで、cookie-universal-nuxt を利用することで、この煩わしさから開放されます。
yarn add cookie-universal-nuxt
module.exports = {
modules: [
['cookie-universal-nuxt', {parseJSON: false}]
]
}
<script>
export default {
asyncData({app}) {
const hoge = app.$cookies.get('hoge')
// ...
}
}
</script>
Google Tag Manager の利用
Google Analytics の設定や、Intercom、各種マーケティングツールを利用については、開発者だけでなくマーケターによる設定などにも対応させるため、Google Tag Manager (GTM) を利用しています。
Nuxt.js で GTM を利用する場合、 @nuxtjs/google-tag-manager
が便利です。
yarn add @nuxtjs/google-tag-manager
nuxt.config.js では、モジュール設定で、GTMのIDを指定する。
module.exports = {
modules: [
['@nuxtjs/google-tag-manager', {id: 'GTM-XXXXX'}]
]
}
このとき、GTMは NODE_ENV=production
の環境でしか動かないことに留意が必要です。
GTM経由で、ページ遷移時に pageview を発生させるために、plugins を作ります。
これは、悩みどころですが、ページタイトル(title
)が、routerの afterEach が発生した直後では、変更されていないことがありました。vue-meta
による反映タイミングの問題かと思いますが、Google Analytics はページタイトル情報を dt
パラメータとして送付するため、違うものを送られるのは解析上困る可能性があります。
ここでは、500msほど後に、changeurl
イベントを発生させる挙動にして対処しました。なかなか苦しい対処な気もします。
export default ({app}) => {
const DELAY_CHANGE_URL = 500
let created = false
const gtm = app.gtm = {
push (object = {}) {
if (!window.dataLayer) return
window.dataLayer.push(object)
}
}
gtm.push({event: 'pageview'})
app.router.afterEach(() => {
Vue.nextTick(() => {
setTimeout(() => {
if (created) gtm.push({event: 'changeurl'})
created = true
}, DELAY_CHANGE_URL)
})
})
}
module.exports = {
plugins: [
'~/plugins/gtm.js'
]
}
GTM のほうでは、changeurl, pageview イベントを受け、Google Analytics の pageview イベントを発生させるように設定します。
AWS Lambda 上で動作させる
以前紹介した方法で、AWS Lambda上で動作させ、特に問題なく1ヶ月が経過しました。ほぼタダでした。(悲しいような。嬉しいような。)
Nuxt.js の仕組みとして最初の1回目だけLambdaが実行され、ページ遷移時は呼び出されません。実行回数はPVというよりは、訪問回数で推測することができます。