components icon indicating copy to clipboard operation
components copied to clipboard

Hydration error with scoped slots

Open gpanos opened this issue 3 years ago • 12 comments

Hi all, There are some issues rendering slotted components and using this module with components auto discovery enabled. Original issue

I think an example will illustrate the problem better: Having a simple slotted component: Let's call it Card.vue

<template>
  <div>
    <div>
      <slot name="title"></slot>
    </div>
    <div>
      <slot name="content"></slot>
    </div>
  </div>
</template>

<script>
export default {}
</script>

Having a simple component let's call it Text.vue

<template>
  <div>
    Random text
  </div>
</template>

<script>
export default {}
</script>

Now using these components together throws a hydration error:

    <Card>
        <template #title>
          <Text />
        </template>
        <template #content>
          <Text />
          <Text />
        </template>
    </Card>

    <Card>
        <template #title>
          <Text />
        </template>
        <template #content>
          <Text />
          <Text />
        </template>
    </Card>
[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>.

The really weird part is that using the same markup just once doesn't throw an error.

    <Card>
        <template #title>
          <Text />
        </template>
        <template #content>
          <Text />
          <Text />
        </template>
    </Card>

No error

Original issue Sandbox to reproduce Sandbox to prove it's working with simple vue-cli and vue-server-render application Sandbox to prove it's working in Nuxt without component auto discovery Related issues

Thanks a lot in advance everyone, I am trying to dig dipper into this and help as much as I can so let me know if I can provide anything more to help you out.

gpanos avatar Mar 09 '21 10:03 gpanos

I have the same issue, and for resolved I import manually the components inside slot. But it's better if I don't have to do this. With the previous version it's work perfectly

joffreyBerrier avatar Mar 09 '21 20:03 joffreyBerrier

@joffreyBerrier For now you should be able to use this as a workaround:

  components: {
    loader: true
  }

(Note: not recommended nor guaranteed to always work.)

A linked issue: https://github.com/nuxt/nuxt.js/issues/8879

danielroe avatar Mar 16 '21 10:03 danielroe

The issue is that we components v2, we use async imports in dev mode without loader. This causes https://github.com/nuxt/nuxt.js/issues/6844 and https://github.com/vuejs/vue/issues/10391. So there is not much do do in nuxt side other than explicitly importing components or force enabling loader: true for development (it makes build slower)

pi0 avatar Mar 16 '21 10:03 pi0

Enabling the loader does not help - it does not fix the reproduction sandbox either 😢

Edit: the sandbox needed a restart - thanks @danielroe

schneefux avatar Mar 16 '21 11:03 schneefux

@schneefux It fixes the reproduction sandbox for me 🙂

danielroe avatar Mar 16 '21 11:03 danielroe

Waiting for upstream: https://github.com/vuejs/vue/pull/11963

pi0 avatar Mar 16 '21 12:03 pi0

But @pi0 however on version 2.14.12 of nuxt which uses nuxt/components V1 it works fine, why it doesn't work anymore I don't understand. So the solution is to import each component in a slot like old way ?

joffreyBerrier avatar Mar 16 '21 18:03 joffreyBerrier

@joffreyBerrier This is because with v2, during development instead of using loader to import components, we use global async components. This significantly improves development build but also revealed this bug in vue. In the meantime, you can enable loader in development (https://github.com/nuxt/components/issues/164#issuecomment-800125711) to use v1 behavior.

pi0 avatar Mar 16 '21 19:03 pi0

I thought that the auto import was "just an automatic import of components" in the components folder but it's more complicated thank's :) So you advise me to import the components that are in slots like the old way and that's it ?

joffreyBerrier avatar Mar 16 '21 20:03 joffreyBerrier

So you advise me to import the components that are in slots like the old way and that's it?

For now yes or use loader: true if you have lots of components affected by this condition.

pi0 avatar Mar 16 '21 20:03 pi0

@pi0 Upstream was merged btw

MrBirb avatar Jul 23 '21 18:07 MrBirb

I'm having the same issue, even with loader: true 🤔

antinomy-studio avatar Jun 13 '22 10:06 antinomy-studio