Motomichi Works Blog

モトミチワークスブログです。その日学習したことについて書いている日記みたいなものです。

Nuxt3とVuetifyを使っているときに Hydration children mismatch in <div>: server rendered element contains fewer child nodes than client vdom. のwarnが出たので解消する

参考にさせていただいたページ

問題のコード

例えば以下のような感じで v-select を使用すると [Vue warn]: ... と出力されます。

<template>
  <div class="index-page">
    <v-select
      :items="[
        { id: -1, name: '選択してください', value: -1 },
        { id: 1, name: 'name1', value: 1 },
        { id: 2, name: 'name2', value: 2 },
      ]"
      item-title="name"
    />
  </div>
</template>

<style scoped lang="scss">
.index-page {
  font-size: 16px;
}
</style>

consoleに出力されたwarnの一部

以下のように出力されました。

runtime-core.esm-bundler.js:40
[Vue warn]: Hydration children mismatch in <div>: server rendered element contains fewer child nodes than client vdom. 
  at <VOverlay ref=Ref< undefined > class="v-menu" activator="parent"  ... > 
  at <VMenu modelValue=false onUpdate:modelValue=fn<onUpdate:modelValue> activator="parent"  ... > 
  at <VField ref=Ref< undefined > onMousedown=fn<onMousedown> onClick:control=fn<onControlClick>  ... > 
  at <VInput ref=Ref< undefined > modelValue="" onUpdate:modelValue=fn<onUpdate:modelValue>  ... > 
  at <VTextField ref=Ref< undefined > autofocus=false counter=false  ... > 
  at <VSelect items= (3) [{…}, {…}, {…}] item-title="name" > 
  at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > > 
  at <Anonymous key="/" routeProps= {Component: {…}, route: {…}} pageKey="/"  ... > 
  at <Anonymous > 
  at <RouterView name=undefined route=undefined > 
  at <NuxtPage> 
  at <Default > 
  at <Anonymous key="default" name="default" hasTransition=false > 
  at <Anonymous > 
  at <Anonymous> 
  at <App key=1 > 
  at <NuxtRoot>

スクリーンショットも載せておきます。

解消方法

以下のように client-only コンポーネントで囲うと解消されます。

<template>
  <div class="index-page">
    <client-only>
      <v-select
        :items="[
          { id: -1, name: '選択してください', value: -1 },
          { id: 1, name: 'name1', value: 1 },
          { id: 2, name: 'name2', value: 2 },
        ]"
        item-title="name"
      />
    </client-only>
  </div>
</template>

<style scoped lang="scss">
.index-page {
  font-size: 16px;
}
</style>