Open Evertvdw opened 2 years ago
I have done some more investigation into this and updated the reproduction. It seems to have to do specifically with render-function
components which quasar uses.
The relevant code snippet:
<component :is="getComponent(col.block)" :dynamicOptions="col.blockOptions">
<!-- it seems that the 'slot' variable in this loop is not available in the component inside it. Also tried `#slot[slot.name]="slot"` but that does not render anything. It will prevent the error though ¯\_(ツ)_/¯ -->
<template
v-for="(slot, slotIndex) in col.slots"
:key="slotIndex"
#[slot.name]
>
<!-- Notice the slot?.columns, without the question mark it will produce an error and not render at all, as slot will be undefined -->
<component
:is="getComponent(column.block)"
v-for="(column, columnIndex) in slot?.columns"
:key="columnIndex"
v-bind="column.blockOptions"
/>
</template>
</component>
In the second for loop the slot
property defined in the for loop above is undefined when using render functions inside SSR. When the loaded component is a SFC there is no issue. I have very little knowledge about render functions so would appreciate some help with this. Maybe Quasar is missing something in the render function or there is some issue in Vue regarding this specific use of render functions.
Maybe this is related? https://github.com/vuejs/vue/pull/12265
I reduced the reproduction complexity and pinpointed the issue to this snippet:
<q-expansion-item>
<template v-for="(slot, slotIndex) in slots" :key="slotIndex" #[slot]>
<div>
{{ slot }}
</div>
</template>
</q-expansion-item>
import { QExpansionItemSlots } from 'quasar';
const slots: (keyof QExpansionItemSlots)[] = ['header', 'default'];
Where slot will be undefined in SSR inside the template.
Ok, did some more digging into this. I made a reproduction without using QExpansionItem
but creating a custom render function component.
I also found that when placing the component (QExpansionItem or the Custom one) directly inside Index.vue
, or some other root level component used inside router.js
it will not give an Hydration error. However when you nest it 1 level deeper the exact same component will produce an hydration error.
See the components I updated here: https://stackblitz.com/edit/quasarframework-vxlqfr?file=src%2Fcomponents%2FExpansionItem.vue,src%2Fpages%2FIndexPage.vue
@rstoenescu Is this something you can work with? I want this fixed really badly, otherwise I will have to create my own custom QExpansionItem :(
I was able to replicate the issue on the SFC playground, so I created an issue in the Vue repo also: https://github.com/vuejs/core/issues/7609. Hopefully it will be picked up there.
What happened?
We are building a cms system that will store information as JSON somewhere and render that at the server/client side. We also define slot content in there for quasar components and when using the QExpansionItem we get an hydration error when doing SSR.
It seems somehow the slot content is empty, with some effort I was able to make a minimal example where I replicate the JSON structure we use.
Inside the
ExpansionItem.vue
there are two slots (header and default) that can be filled with 1 or more components defined in the JSON structure. Inside theItemContentBlock
there is av-for
that loops through the slots and inside the slot anotherv-for
that loops through the columns of that slot.I also commented out a simple HTML collapse inside
ExpansionItem
using adetails
andsummary
element, that does not have the hydration errors. So it seems to be something specific to the ExpansionItem.What did you expect to happen?
No hydration errors
Reproduction URL
https://stackblitz.com/edit/quasarframework-vxlqfr?file=src/components/ExpansionItem.vue
How to reproduce?
Flavour
Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)
Areas
Components (quasar), SSR Mode
Platforms/Browsers
Chrome
Quasar info output
No response
Relevant log output
No response
Additional context
No response