Skip to content

Commit 9698dd3

Browse files
committed
fix(ssr): fix hydration mismatch when entire multi-root template is stringified
fix #6637
1 parent 0382019 commit 9698dd3

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

packages/runtime-core/__tests__/hydration.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,14 @@ describe('SSR hydration', () => {
982982
expect((container as any)._vnode).toBe(null)
983983
})
984984

985+
// #6637
986+
test('stringified root fragment', () => {
987+
mountWithHydration(`<!--[--><div></div><!--]-->`, () =>
988+
createStaticVNode(`<div></div>`, 1)
989+
)
990+
expect(`mismatch`).not.toHaveBeenWarned()
991+
})
992+
985993
describe('mismatch handling', () => {
986994
test('text node', () => {
987995
const { container } = mountWithHydration(`foo`, () => 'bar')

packages/runtime-core/src/hydration.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export function createHydrationFunctions(
108108
)
109109

110110
const { type, ref, shapeFlag, patchFlag } = vnode
111-
const domType = node.nodeType
111+
let domType = node.nodeType
112112
vnode.el = node
113113

114114
if (patchFlag === PatchFlags.BAIL) {
@@ -150,9 +150,12 @@ export function createHydrationFunctions(
150150
}
151151
break
152152
case Static:
153-
if (domType !== DOMNodeTypes.ELEMENT && domType !== DOMNodeTypes.TEXT) {
154-
nextNode = onMismatch()
155-
} else {
153+
if (isFragmentStart) {
154+
// entire template is static but SSRed as a fragment
155+
node = nextSibling(node)!
156+
domType = node.nodeType
157+
}
158+
if (domType === DOMNodeTypes.ELEMENT || domType === DOMNodeTypes.TEXT) {
156159
// determine anchor, adopt content
157160
nextNode = node
158161
// if the static vnode has its content stripped during build,
@@ -169,7 +172,9 @@ export function createHydrationFunctions(
169172
}
170173
nextNode = nextSibling(nextNode)!
171174
}
172-
return nextNode
175+
return isFragmentStart ? nextSibling(nextNode) : nextNode
176+
} else {
177+
onMismatch()
173178
}
174179
break
175180
case Fragment:

0 commit comments

Comments
 (0)