Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<component> of void element with content causes hydration mismatch #12136

Open
Ingramz opened this issue Oct 9, 2024 · 2 comments · May be fixed by #12137
Open

<component> of void element with content causes hydration mismatch #12136

Ingramz opened this issue Oct 9, 2024 · 2 comments · May be fixed by #12137

Comments

@Ingramz
Copy link

Ingramz commented Oct 9, 2024

Vue version

3.5.11

Link to minimal reproduction

https://play.vuejs.org/#__SSR__eNqFVNtu00AQ/ZXBLwEptUnKTVZSCapKwEOpAPGCK+TYE2fLene1u3ZTRf53ZnxJ3CgKebAyZy4+M3PGu+CjMWFdYRAHC5dZYTw49JW5SpQojbYerrXyqPytzhHWVpcwCaMRxsmTRCUq08p5oCd7YAm/EwWw4weAfzIYwwQlluScTDtUpSWjZrBT761YVR5dDLumB/uCcVePf33NUV2P233RFiab4M8opYZHbWX+gih2vqHuqTpH/EYcRVmM0WdMwdmMQjbeGxdHUVqnPrUuLITfVKvKoe1bCDNdRlX0bjb/MHv9fjKFVDLLXxWGD24yIjZu+n6PDv4OYes+UYuoWxqtiwyPpZGpR7IAFrmoIZOpc8sk6AsmQesi53ir9cVaWwpSbAg1vD0JIGao95AZdYUjqkz/FtHofcE08I4S16KgbrQiPbXz5VeXRki034wXJJEkoJF1JJIgpQU9fm0xbyvsO6ScDWZ/T+APbstYEtxZpMHWRGrvo6EXSKTZffPjliQwcpY6ryRFn3F+R6dlxRy7sE+Vyon2KK5l+6W9CqGKn+5mS2NyQ1NMdNgMR9NdXJ9p/UD3MnzT5iWqoSkendbxXYJMVUEb8VSNxp7jWii8s9q4xQ54TTGk6gmaq5evzquD16IVn2osWCGcG7Laac/1hVgPEJ8GLJfLw3W0ASuh8iHkcA3/19ecBdZmnVbZfCSzPcXOHvhTPZQOT3JsvwTEYtcNI2QbmuaZVI91+6dGy1ukUV+Gb8PZLGj+AeRfpSE=

Steps to reproduce

Reproduction contains an example where a component called ContentNode references itself while rendering a tree of content elements. When enabling SSR, hydration mismatches are reported, but when comparing the generated HTML, everything seems OK.

What is expected?

No hydration mismatches.

What is actually happening?

Hydration mismatches are reported.

System Info

No response

Any additional comments?

No response

@edison1105
Copy link
Member

edison1105 commented Oct 10, 2024

I'm not sure if this counts as a bug, but the issue is that the vnode of img contains children, which is unreasonable because the img tag is self-closing and cannot have children. Maybe we should ignore the children of void tags when creating vnode.

You shouldn't add child nodes to the img tag, as it is unreasonable. You can modify it like this:

<template>
  <component :is="node.name" v-if="node.type === 'element' && node.name !== 'img'" v-bind="node.attributes">
    <ContentNode v-for="node2 in node.content" :node="node2" />
  </component>
  <template v-else-if="node.type === 'text'">{{ node.text }}</template>
  <img v-else-if="node.name === 'img'" v-bind="node.attributes" />
</template>

Note: this will still report a mismatch in Playground because there is a bug in Playground, but it works correctly when the project is started locally.

@Ingramz
Copy link
Author

Ingramz commented Oct 10, 2024

Thank you for investigating, I can confirm that you are correct that creating a dedicated else-if branch for void elements with no content easily works around this. Playground reporting hydration mismatches despite not using a void element was driving me insane. 🤦

Also now that you explained that the img vnode still contains children, then if I understand correctly, when comparing to the rendered HTML, which does not contain any children, it triggers the mismatch.

As for how to better handle this situation, I have no strong preference, but if the children on a void element vnode do not contribute to rendered HTML / DOM, they should be treated as valid and matching. If something visible was rendered, then that should still continue be treated as hydration mismatch due to the resulting HTML being invalid.

@Ingramz Ingramz changed the title SSR generated code causes hydration mismatch for a recursive component <component> of void element with content causes hydration mismatch Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants