Open DamianGlowala opened 3 years ago
I have this exact issue, I'm surprised nobody faced this issue before.
v-calendar (v-date-picker)
is not SSR compatible, so I wrap in client-only.
This cause an SSR error:
vue.runtime.esm.js?2b0e:6427 Mismatching childNodes vs. VNodes: NodeList [comment], NodeList [VNode] I thought the problem was with
v-calendar
, but I still get the error if I only useclient-only
and standard HTML inside.
Here is my exact component.
<template>
<v-widget :name="$t('agenda')">
<div>
<client-only>
<div class="flex-container">
<v-date-picker v-model="selectedDate" :attributes="attributes" is-required />
<div class="events">
[...]
</div>
</div>
</client-only>
</div>
</v-widget>
</template>
And here is v-widget
:
<template>
<div class="widget">
<h2 class="widget-name">{{ name }}</h2>
<slot></slot>
</div>
</template>
From my understanding, Vue think it has to render a comment <!-- -->
(the SSR placeholder), but on the client side, it realise it need to render a <div>
which trigger the missmatch.
Wrapping my slot in a <div>
seems to fix the issue, but it's not actually possible in my case because of how my flex layout is made.
<template>
<div class="widget">
<h2 class="widget-name">{{ name }}</h2>
<div>
<slot></slot>
</div>
</div>
</template>
My problem was with Nuxt component autoload/discovery. Replacing this with a plugin that manually import my global components fixed the problem.
components: [
{ path: '@/components/global', global: true },
],
Hey, I'm also stuck with a similar issue, as you can see in this code sandbox -- https://codesandbox.io/s/vue-horizontal-calendar-nuxt-demo-myytd?file=/pages/index.vue I am able to render component normally but if I pass it inside a template slot it's not rendering.
vue-horizontal-calendar is the component, I have declared twice but the one outside template is the only one rendering
One tiny workaround I found for now is by removing scoping to the template and using the slot where we have to pass the component as the default slot and template. So this basically - https://codesandbox.io/s/vue-horizontal-calendar-nuxt-demo-forked-hvx9e?file=/pages/index.vue
Had the same issue that I worked around by wrapping the entire component in the client only instead of the slot.
Initially, triggering the issue
<my-component>
<client-only>{{ foobar }}</client-only>
</my-component>
The current fix, not ideal but works in our case
<client-only>
<my-component>{{ foobar }}</my-component>
</client-only>
Not perfect, but I believe its possible to overcome this issue by rewriting <client-only>
to a regular, stateful component. You lose of course some benefits or functional components (rendering multi root elements or performance), but at least renders slot content properly.
render(h) {
if (this._isMounted) {
return this.$slots.default;
}
this.$once('hook:mounted', () => {
this.$forceUpdate();
});
if (this.placeholderTag && (this.placeholder || this.$slots.placeholderSlot)) {
return h(
this.placeholderTag,
{
class: ['client-only-placeholder']
},
this.placeholder || this.$slots.placeholderSlot
)
}
return this.$slots.default && this.$slots.default.length > 0 ? this.$slots.default.map(() => h(false)) : h(false)
}
Just faced this issue again in 2023. The problem is not with slot in general, but with named slots.
For exemple, this will work since it's a default slot (the <template>
is not even necessary as eslint points-out)
But this won't work for some reason, still a default slot, but I added #default
on the template.
What seem to have worked for me was to use slot="slotName"
instead of v-slot:slotName
or the #slotName
shorthand
I can verify, this problem is still existing in 2024.
Original issue reported at nuxt/nuxt.js#8579.
The content inside
<client-only>
tag doesn't render when the tag is placed in a component's slot of another component's slot, as shown in the following reproduction: codesandbox@egoist any chance you could look into this issue please? I can see the repo hasn't been updated in a while but this missing functionality is crucial for some use-cases, when client-only tag is the only way to go in the nested slots structure :/