Nuxtのvuex-persistedstateをSSRで使ってみる

背景

NuxtのSSRを行うライフサイクルにてvuex-persistedstateによるvuexのデータの更新が行えなかったことが今回のつまずき、解決するのにかなり時間を要したので記事にしました。

前提

vuexの短所としてリロードをするとstoreのデータが消えてしまうため、vuex-persistedstateを用いてcookieに保存していました。 しかし、asyncDataなどのSSRのライフサイクルにおいて、vuexの更新はSPA(CSR)側のcookieに反映されず、 結果としてvuexの更新がなされない問題が生じておりました。 vue-persistedstateに関しては、こちらを参考にしてください

実装方法(サンプルコード)

色々探してみたところ、こちらのissueで解決されており、cookie-universal-nuxtを使うとSSRでもvuexの更新が行えるとのことでした。

以下のコマンドでcookie-universal-nuxtをインストールしてください

# npmの場合こちら
npm i --save cookie-universal-nuxt
# yarnの場合こちら
yarn add cookie-universal

設定を追加する

moduleを扱うためにnuxt.config.jsに追加する

{
  modules: [
    // 追加
    'cookie-universal-nuxt',
 ]
}

pluginを実装する

moduleに追加すると、勝手に$cookiesとしてinjectされます。

{
  plugins: [
    // 追加
    '~/plugins/persistedstate.js'
  ],
}
import createPersistedState from 'vuex-persistedstate';
export default ({store, app}) => {
    // ...
    createPersistedState({
        storage: {
            getItem: (key) => app.$cookies.getAll()[key],
            setItem: (key, value) => app.$cookies.set(key, value, { path: '/', maxAge: 60 * 60 * 24 * 7, secure: true }),// 7日間保持
            removeItem: (key) => app.$cookies.remove(key),
        }
    })(store)
}

動作の例

以下のようにするとSSR時にもstoreが更新されます。

// ログイン必須のページ
<script>
  export default {
    async asyncData({ store }) {
    .....
        if (!store.token) {
            const { data } = await login(this.input);
            this.$store.commit('setToken', data.token);
        }
    .....
    }
  }
</script>

こちらの情報が誰かに役立てれば幸いです!

参考