概要
Nuxtを利用していて以下のエラーに遭遇した。ただ、yarn run build
を利用した際は問題ないのに、yarn run generate
をしたら、これが起こる。
[nuxt] Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
本題
実は開発環境でも、上記のエラーが発生する兆候は表れている。開発者ツールのエラーメッセージを眺めていると、以下のようなメッセージが表示される。生成された html と component を利用してレンダリングをする html が異なる場合、このエラーが発生するらしい(楽勝すぎるはずの netlify form を nuxt generate で頑張って使う)。
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
確かにレンダリングされるDOMの不一致が発生しているとのこと。
この問題の原因は、v-if
による表示制御をしていることが問題であり、解決策の一つとして、v-show
に置き換えることで解決することができる。この理由は、v-show
を利用した場合、v-show="false"
の値について注目すると、生成されたDOMはdisplay:none
で見えなくされており、v-if
の場合はそうではなく、サーバ側ではv-if="false"
でもDOM自体は生成されており、クライアント側ではv-if="false"
のDOMはレンダリングされないため、レンダリング結果に差異があるため、エラーが発生するものと考察した。
ただ、v-show
ではdisplay:none
のスタイルがあたっているだけなので、開発者ツールで見ようと思えば見えてしまう。
あまり、こうしたくない場合は、<no-ssr></no-ssr>
で囲うことで、DOMの差分も発生せず、かつ、yarn run generate
をしても、エラーが発生することはない。