Search code examples
nuxt3.jshydration

Why do I get this hydration warning when using useState in Nuxt 3?


MRE: https://github.com/Morpheu5/nuxt3-hydration-mre (was https://box.morpheu5.net/s/H6WXBfCebrRyTa8)

According to the docs, useState in NuxtJS 3 is supposed to be the SSR-friendly lightweight way of creating state. I need to use this so that any page/[somepage].vue can set some data to be used by layout/default.vue. This is a page:

<template>
    <div>Some page content.</div>
</template>

<script setup>
    useState('page_title', () => 'Some page title');
</script>

and this is the default layout:

<template>
    <div>
        <h1>{{ page_title }}</h1>
        <slot />
    </div>
</template>

<script setup>
    const page_title = useState('page_title');
</script>

When I run this in development mode, I get this warning in my browser's console:

runtime-core.esm-bundler.js:38 [Vue warn]: Hydration text content mismatch in <h1>:
- Client: 
- Server: Some page title 
  at <Default > 
  at <AsyncComponentWrapper > 
  at <BaseTransition mode="out-in" appear=false persisted=false  ... > 
  at <Transition name="layout" mode="out-in" > 
  at <Anonymous> 
  at <App key=1 > 
  at <NuxtRoot>

I know it's just a warning, and I don't get the warning if I generate and deploy statically (which is my goal anyway) but I was wondering if this is indicative of a deeper issue somewhere that I'm overlooking.

Also worth pointing out that the generated html does not "pre-render" the default value that I specify in the page, but this may just be my own misconception of how this works and I may be wrong to expect this to happen.


Solution

  • The hydration warning is caused by the fact that the server had rendered an empty <h1> where the client renders some text in it.

    On SSR passing up state (e.g. here from page to layout) won't work.

    You can avoid the hydration error by wrapping the title with <client-only>...</client-only> which will disable the SSR for this part. Thus there is no surprise (aka hydration warning) that the content differs.