Subscribe on changes!

Hydration mismatch warning when using a the renderer function

avatar
Jul 14th 2023

Vue version

^3.2.25

Link to minimal reproduction

https://stackblitz.com/edit/github-6za3kr?file=src%2Fpages%2FHome.vue

Steps to reproduce

Check the console.log.

The repo also has an additional component that uses directly the h render function (thus, no lib), but the error is the same. Might be useful for debugging.

What is expected?

No warnings to appear

What is actually happening?

A warning message is being thrown

Vue warn]: Hydration text mismatch:
- Client: "When we launched in 2006, our ambition was simple: help businesses grow. We started with payments, taking an engineering-first approach to solving some of the most complex challenges. Today, we are the preferred financial technology platform of many of the world's leading brands. We did this by working with exceptional talent, prioritizing success over ego, and having fun along the way."
- Server: "When we launched in 2006, our ambition was simple: help businesses grow. We started with payments, taking an engineering-first approach to solving some of the most complex challenges. " 
  at <RichText document= Objectcontent: Array(2)0: {data: {…}, content: Array(6), nodeType: 'paragraph'}content: (6) [{…}, {…}, {…}, {…}, {…}, {…}]data: {}nodeType: "paragraph"[[Prototype]]: Object1: {data: {…}, content: Array(1), nodeType: 'paragraph'}length: 2[[Prototype]]: Array(0)data: {}nodeType: "document"[[Prototype]]: Object > 
  at <RichText> 
  at <App key=2 > 
  at <NuxtRoot>
warn2 @ chunk-Q53DPCWL.js:1381

System Info

No response

Any additional comments?

When using a rich-text renderer, I stumbled upon an hydration mismatch warning. Upon research, I have narrowed it down to the h render function from vue.

We've discussed it a little bit in this issue in the nuxt project, and @danielroe suggests that it is related to how vue handles whitespaces.

Happy to investigate more or help in any way.

avatar
Jul 16th 2023

Maybe duplicate of https://github.com/vuejs/core/issues/7775 /cc @baiwusanyu-c

avatar
Jul 17th 2023

This is different from 7775. The essential problem of 8783 is that it uses contentful-rich-text-vue-renderer (it uses the h function internally). In this process, the virtual nodes generated by both the server and the client are generated by contentful-rich -text-vue-renderer control. Therefore, since the virtual node content of the component is not generated from the vue compiler, these virtual nodes are somewhat uncontrollable. In a minimal reproduction of 8783 parameter:

{
           data: {},
           marks: [],
           value: 'xxxxxxxx',
           nodeType: 'text',
},
{
           data: {},
           marks: [],
           value: '. ',
           nodeType: 'text',
},

Two virtual nodes will be generated by contentful-rich-text-vue-renderer. However in the output of server-renderer it is just a html string <div>xxxxxxxx.<div>, so the content of the html will be the same as the The two virtual nodes (xxxxxxxx and .) generated by contentful-rich-text-vue-renderer cause a mismatch. I'm not sure if this is a bug, because using the h function to generate virtual nodes on the client and server itself is uncontrollable. Unless we can make enhancements to server-renderer to solve it

这与7775不同,8783的本质问题在于使用了contentful-rich-text-vue-renderer(它内部使用了h函数),在这个过程中无论是服务端还是客户端生成的虚拟节点都由contentful-rich-text-vue-renderer控制。因此组件的虚拟节点内容由于并不是从vue的编译器产生,这些虚拟节点存在一定的不可控性。在8783的最小复现中 参数:

{
          data: {},
          marks: [],
          value: 'xxxxxxxx ',
          nodeType: 'text',
},
{
          data: {},
          marks: [],
          value: '. ',
          nodeType: 'text',
},

会被contentful-rich-text-vue-renderer生成两个虚拟节点。然而在server-renderer的输出中,它仅仅是一个html字符串 <div>xxxxxxxx.<div>, 因此在水合的过程中html的内容会与 contentful-rich-text-vue-renderer 生成的两个虚拟节点(xxxxxxxx 与 .)造成不匹配。我不确定这是否是bug,因为使用h函数在客户端与服务端自行生成虚拟节点本身就存在不可控性。除非我们能对server-renderer做出增强来解决它

avatar
Jul 17th 2023

thanks @baiwusanyu-c duplicate of https://github.com/vuejs/core/issues/7285