揚げログ

Karaage(krgpi)の技術開発関連のブログです

SSRで使えないライブラリをSSRで使う - Nuxt.js

状況

Nuxt.jsでwebサービス開発をしていると、SSRで使えないライブラリをSSRで使いたい時がある。例えば、

  • DOMにアクセスするライブラリ

(SSRで使うと毎回orページリロード時にdocument is not defined, window is not definedのようなエラーが発生する)

回避方法

ここでは、vue-grid-layoutというライブラリを例にする。

エラーが出る例

<template>
  <v-container>
    <grid-layout>
     ...
    </grid-layout>
  </v-container>
</template>

<script>
import VueGridLayout from "vue-grid-layout"
...
export default {
...
}
</script>

成功例

<template>
  <v-container>
    <client-only>
        <grid-layout>
     ...
        </grid-layout>
    </client-only>
  </v-container>
</template>

<script>
// import VueGridLayout from "vue-grid-layout" ここでインポートしない
export default {
    ...
    created(){
           if (process.client) { //clientでの実行ならば
              require("vue-grid-layout");
          }
    }
}

まとめ

  1. ライブラリを使うコンポーネントのhtmlタグ部分を、 <client-only> で囲う

参考: https://ja.nuxtjs.org/api/components-client-only/

  1. ライブラリのインポートを created() で行う

createdはVueインスタンスが生成された直後に実行される。これをasyncDataとかでやると、まだDOMがないのでエラー(document is not defined)になる。

参考: http://lab.astamuse.co.jp/entry/2019/05/29/114500

  1. if (process.client) {} で囲む

created()はサーバー側・クライアント側両方で実行されるが、このif文を入れておくことで、確実にサーバー側での実行をブロックできる。