Hydration errors style attribute since vue 3.4
Vue version
3.4.19
Link to minimal reproduction
https://github.com/vuejs/core/discussions/10335
Steps to reproduce
- Create 2 DOM elements any ssr
- Create dependence style first element from style another, for example
<div :style="{ paddingRight: `${width + 10}px` }">
Content
</div>
<button ref="cartButton">
Cart button
</button>
const cartButton = ref<HTMLElement>()
const { width } = useElementSize(cartButton, undefined, {
box: 'border-box'
})
I tried using the onMounted hook but it doesn't seem to guarantee that the hydration process is complete, it seems like a bug. Is this really something that deserves warning?
this is more of a theoretical question, so I don't think reproduction is necessary, you can reproduce it in any minimal SSR
It seems that any style dependency on another style that changes on the client will give an error. We don't understand the concept?
What is expected?
No hydration errors
What is actually happening?
Hydration errors
System Info
System:
OS: macOS 14.3
CPU: (8) arm64 Apple M1
Memory: 69.20 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.5.1 - ~/.nvm/versions/node/v20.5.1/bin/node
npm: 9.8.0 - ~/.nvm/versions/node/v20.5.1/bin/npm
Browsers:
Chrome: 121.0.6167.160
Safari: 17.3
npmPackages:
vue: ^3.4.19 => 3.4.19
Any additional comments?
No response
upd. isMounted inside a component solves the problem, but should we add a check everywhere? It's almost as if :style itself is defective
:style="{ paddingRight: isMounted ?
${widthCartButton + 10}px : 0 }"
upd2. Is there some kind of lifecycle hook that would indicate the end of hydration of the entire application?
We don't know what useElementSize
is doing underneath, please provide a runnable reproduction instead of code snippets.
We don't know what
useElementSize
is doing underneath, please provide a runnable reproduction instead of code snippets.
I made minimal reproduction: https://github.com/DaniilIsupov/reproduction-hydration
In my example at App.vue
I can't wait when all child components are mounted
Because of this prop.count
value is being updated until hydration is complete
We don't know what
useElementSize
is doing underneath, please provide a runnable reproduction instead of code snippets.I made minimal reproduction: https://github.com/DaniilIsupov/reproduction-hydration In my example at
App.vue
I can't wait when all child components are mounted Because of thisprop.count
value is being updated until hydration is complete
Yes, this is the crux of the problem
useElementSize is a VueUse helper, but that's not important
The fact is that in large difficulty applications, some components are mounted before others, which leads to hydration errors when changing some parameters depending on the client side. In my case, VueUse useElementSize passes the width from the client and causes the style attribute of the not yet mounted component to change and throws an error
However, this is very difficult to reproduce in a minimal example, since the components are mounted almost simultaneously
Therefore, when accessing a client entity in one place, we cannot be sure that all components in which changes will occur have already been mounted and hydration has been completed