core: Hydration class/style/attr mismatch on SSR components

Vue version

3.4.7

Link to minimal reproduction

https://stackblitz.com/edit/nuxt-starter-14rqc1

Steps to reproduce

Visit the reproduction Link. IMPORTANT: The viewport have to be large. I have extended the browser to my second monitor to increase the website width size.

What is expected?

There should be no vue warns

What is actually happening?

There are mismatch vue warns

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (32) x64 Intel(R) Core(TM) i9-14900KF
    Memory: 36.76 GB / 63.85 GB
  Binaries:
    Node: 20.10.0 - C:\Program Files\nodejs\node.EXE
    npm: 9.9.2 - ~\<privacy-deleted>\node_modules\.bin\npm.CMD
  Browsers:
    Chrome browser: 120.0.0.0

Any additional comments?

This happens since Vue 3.4.5

[Vue warn]: Hydration class mismatch on <div class=​"v-slide-group v-slide-group–has-affixes v-slide-group–is-overflowing" style tabindex=​"0">​…​</div>​

  • rendered on server: class=“[object Set]”
    • expected on client: class=“[object Set]” Note: this mismatch is check-only. The DOM will not be rectified in production due to performance overhead. You should fix the source of the mismatch. at <VSlideGroup show-arrows="" >

This also happens with other components, VNavigationDrawer and VBanner, all of them using computed display classes --mobile. Don’t know if this has anything to do with: /vuetify/src/composables/display.ts const displayClasses = computed(() => { … }

Another similar bug has been solved recently in Vue v3.4.6 https://github.com/vuejs/core/issues/10006

As I don’t know how to reproduce the error without Vuetify and have no idea what is exactly the root cause of this issue, I am opening the same issue in both projects.

Link to Vuetify issue: https://github.com/vuetifyjs/vuetify/issues/19002

About this issue

  • Original URL
  • State: closed
  • Created 6 months ago
  • Comments: 18 (5 by maintainers)

Most upvoted comments

With Nuxt Image I’m getting a lot of hydration errors on the latest Vue (3.4.9)

  - rendered on server: referrerpolicy="undefined"
  - expected on client: referrerpolicy=""
  
  - rendered on server: usemap="undefined"
  - expected on client: usemap=""
  
  - rendered on server: crossorigin="undefined"
  - expected on client: crossorigin=""
  
  - rendered on server: loading="auto"
  - expected on client: loading=""
  
  - rendered on server: decoding="auto"
  - expected on client: decoding=""

With the latest version this isn’t fixed however the amount of mismatches have changed. Now I’m getting:

- rendered on server: loading="auto"
- expected on client: loading=""

 - rendered on server: decoding="auto"
- expected on client: decoding=""

With Nuxt Image I’m getting a lot of hydration errors on the latest Vue (3.4.9)

  - rendered on server: referrerpolicy="undefined"
  - expected on client: referrerpolicy=""
  
  - rendered on server: usemap="undefined"
  - expected on client: usemap=""
  
  - rendered on server: crossorigin="undefined"
  - expected on client: crossorigin=""
  
  - rendered on server: loading="auto"
  - expected on client: loading=""
  
  - rendered on server: decoding="auto"
  - expected on client: decoding=""

Should be fixed now by 08b60f5d0 and released in 3.4.11

Still having the same errors

Here is an example: https://stackblitz.com/edit/nuxt-starter-14rqc1

I too agree with the above, some more work is still required to resolve this. I’ve just tested the new release and although it has resolved some of the issues, such as the one with the readonly attribute. This is still occurring on others, such as the list attribute:

[Vue warn]: Hydration attribute mismatch on <input name=​"test" value>​</input>​
  - rendered on server: list="null"
  - expected on client: list=""

Simplified code to reproduce:

<template>
  <input
    name="test"
    :list="dataList.options.lengh > 0 ? dataList.name : undefined"
    value=""
  >
  <datalist :id="dataList.name " v-if="dataList.options.length > 0">
    <option v-for="o of dataList.options||[]" :key="o" :value="o" />
  </datalist>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'testInputComponent',

  setup() {
    return {
      dataList: {
        name: 'test',
        options: []
      }
    }
  }
})
</script>

If the readonly issues are the only ones left then I’m closing this. Please let me know if the class mismatch issue persists.

It looks like changes are being made, let’s see if it solves these problems as well.

https://github.com/vuejs/core/commit/972facee0d892a1b6d9d4ad1da5da9306ed45c3f