The client-side rendered virtual DOM tree is not matching server-rendered content

Versions

  • nuxt: ^2.14.12
  • node: v14.15.4

Reproduction

Hello everyone and thank you in advance. I have a strange issue that I don’t really understand what’s the problem and how to deal with it. I have installed a fresh nuxt ssr project. I’m getting the following warning [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.

I have three simple components: Form, Input, Button. Form.vue

<template>
  <form v-bind="$attrs" class="w-full" @submit.prevent="$emit('submitted')">
    <div class="space-y-2 mb-4">
      <slot name="fields" />
    </div>
      <slot name="button" />
    </div>
  </form>
</template>
<script>
export default {
  computed: {
    hasFields() {
      return !!this.$slots.fields
    },
  },
}
</script>

Input.vue

<template>
  <div class="relative w-full">
    <input class="form-input block w-full" />
  </div>
</template>
<script>
export default {
  inheritAttrs: false,
}
</script>

Button.vue

<template>
  <button
    type="submit"
    class="relative btn inline-flex items-center justify-center transition ease-in-out duration-150"
  >
    Save
  </button>
</template>
<script>
export default {}
</script>

I use my components in pages/index.vue like this:

<template>
  <div>
    <Form>
      <template #fields>
        <Input />
        <Input />
      </template>
      <template #button>
        <Button />
      </template>
    </Form>
    <Form>
      <template #fields>
        <Input />
        <Input />
      </template>
      <template #button>
        <Button />
      </template>
    </Form>
  </div>
</template>

<script>
export default {}
</script>

If i use the Form component only once in the view i don’t get the warning. If i use it twice i get it.

Steps to reproduce

Reproduction link

  1. Install a fresh nuxt ssr project.
  2. Create the components as in the reproduction link

What is Expected?

All the components to render normally without any warnings or errors.

What is actually happening?

I get the following warning. [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.

Some extra notes

  1. I know that wrapping the whole thing inside a <client-only> fixes the problem but i want to understand why is this happening in order to avoid it in future cases.
  2. Also if I remove components: true from nuxt.config.js and import the components normally again the warning is gone.
  3. Changing the name of the components eg ButtonTheButton won’t fix the problem. You can see the reproduction here.
<script>
import Input from '~/components/Input'
import Button from '~/components/Button'
import Form from '~/components/Form'

export default {
  components: { Form, Button, Input}
}
</script>

You missed an opening <div>

<div class="space-y-2 mb-4">
  <slot name="fields" />
</div>
// There should be a <div> here
  <slot name="button" />
</div>

Do you use a linter with your IDE? It should have picked up on this, so I’m guessing not. I highly recommend using one.

@ JamesThomson
Thank you for your response.
Indeed I was missing an opening tag. But even after adding the missing <div> the warning is there. So unfortunately what u suggest doesn’t fix it.

1 Like

@KaragiannidesAgapios
Refer to this article as it will help you.

I’m aware of the article my friend, thank you.
Unfortunately, it doesn’t fix the problem.

Hi @KaragiannidesAgapios
I have gone through your issue and the issue is that you missed an opening

<div>

tag as already said by @JamesThomson now it’s not showing any warning in console,