vue productionで DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.

本稿について

本稿はサイト運営者が学んだことなどを記したメモの内容です。
全てが正確な情報とは限りません。ご注意ください。また修正するべき点は適時修正していきます
Nuxtで本番環境でのみ以下のエラーが発生した。

DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.

調べてみると、localでもproductionモードで起動すると同じような事象が発生。
developモードだと発生しないらしい。

[原因]
完全にNuxtの仕様を把握したわけではないが、
mode: ‘universal’

で起動していると、SSRとSPAが混合して動作している様子。
この時に、componentの中でSPAに依存した 箇所があるとSSRの初期描画時に
エラーが発生するっぽい。

[参考]

具体的には以下のような処理順序
nuxtServerInit -> SSR -> nuxtClientInit -> SPA

以下のように “nuxtClientInit” の中で、サーバーからのレスポンスを待つような処理を
書く

store/index.js
export const actions = {
  // SSR初期時の動作
  nuxtServerInit({ commit }, context) {
    console.log("nuxtServerInit start")
  },
  // SPA初期時の動作
  nuxtClientInit({ commit }, context) {
      let hoge = await axios.get(`${process.env.SERVER_URL}/auth`)
      commit('auth/login', { key: key, auth: hoge } )
    }
  }
}

その上で、一部のcomponentで以下のようにサーバーからの認証情報が必要な処理を書いていたのが問題のようでした。

<template>
  <div>
    <div v-if="checkAuth()”></div>
  </div>
</template>

<script>
...
checkAuth() {
   return this.$store.state.auth.account
},
</script>

[解決策]
結論として SPA依存のコードがあるcomponentに
<client-only placeholder="Loading…”></client-only>
タグを入れてあげることによって解決した

<template>
  <div>
    <client-only placeholder="Loading…">
       <div v-if="checkAuth()”></div>
    </client-only>
  </div>
</template>

[参考]

Back