vuejs3nuxt3.jspinia

Pinia + Hydration node mismatch


I'm new in Nuxt3, and I have an Hydration probleme/Warning.
I use Vue 3 + Nuxt 3 + Pinia to render definitions.
I have a store that get all datas of the definition from a server with an id

stores/article.ts

export const useArticleStore = defineStore('main', {
   state: () => {
        return {
            articleid: {},
            alldata: {} as WordInfo,
            entry: {} as WordEntry,
            otherEditions: {} as { [key: string]: WordEntry },
            //....
        }
   },
   getters...
   actions: {
     async fetchJSonData(articleid : string) {
       const { data : wordInfo} = await useLazyFetch('http://localhost:8080/dictionnaire/article/'+ articleid +'?format=json');
            
            this.alldata = wordInfo.value as WordInfo;
            this.entry = this.alldata.entry;   // for better access
            this.otherEditions = this.alldata.otherEditions; // for better access
            ///...
     }
   }
}

I use the fetch function inside a page => pages/article/[id].vue

<script setup >
  const articleStore = useArticleStore();
  const route        = useRoute();
  const { fetchJSonData } = articleStore; 

  // Get Data
  fetchJSonData(route.params.id);
</script>

then in my components/Grid.vue which is load at the same time as [id].vue thanks to a layout, I want to use the data saved in the store :

<script setup>
const articleStore = useArticleStore();
const {entry, otherEditions, getType} = storeToRefs(articleStore); 
</script>

<template>
   <div class="grid">
 <!-- ... --> 
     <ul id="ulgrid">
          <li class="version" v-for="index in 8" :key="index" :id="'v'+index">
            <a v-if="otherEditions && otherEditions[index]" :href="'/article/' + otherEditions[index]['id']" >
              <div :id="'version'+index" :class="'blocVersion' + isActif(index, entry)">
                  <div class="chiffre">{{ index }}<sup>{{ index == 1 ? 're' : 'e' }}</sup></div>
                  <div class="annee">{{ $constants.editionsYear[index] }}</div> 
              </div>
            </a>
            <div v-else :id="'version'+index" class="blocVersion nonDispo">
                  <div class="chiffre">{{ index }}<sup>{{ index == 1 ? 're' : 'e' }}</sup></div>
                  <div class="annee">{{ $constants.editionsYear[index] }}</div>
              </div>
          </li>
     </ul>
 <!-- ... --> 
   </div>
</template>

The HTML is good but I get a ton of warnings. Since this is a rendering loop, I get 8 similar warnings like this

[Vue warn]: Hydration node mismatch:
- Client vnode: a 
- Server rendered DOM: <div id=​"version1" class=​"blocVersion nonDispo" data-v-inspector=​"components/​Grid.vue:​17:​13">​…​</div>​  
  at <Grid mode="article" > 
  at <Article ref=Ref< undefined > > 
  at <LayoutLoader key="article" layoutProps= {ref: RefImpl} name="article" > 
  at <NuxtLayoutProvider layoutProps= {ref: RefImpl} key="article" name="article"  ... > 
  at <NuxtLayout > 
  at <App key=4 > 
  at <NuxtRoot>

From my understanding, it's seems like the data in my server-side are not correctly fetch compare to my client-side (or not correctly stored)
Can i get ride of those warning or should i live with them ?

Note : Missing import in code are done inside nuxt.config.ts


Solution

  • In reference to this post :
    https://github.com/nuxt/nuxt/issues/15474
    it seems to be an issue with the layout
    I moved "fetchJSonData()" and related code to layout/article.vue and all hydration warnings disappeared.