diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts
index 1c27f321ec8..20519cf997f 100644
--- a/packages/runtime-core/__tests__/hydration.spec.ts
+++ b/packages/runtime-core/__tests__/hydration.spec.ts
@@ -1880,6 +1880,26 @@ describe('SSR hydration', () => {
expect(root.innerHTML).toBe('
')
})
+ test('hmr root reload', async () => {
+ const appId = 'test-app-id'
+ const App = {
+ __hmrId: appId,
+ template: `foo
`,
+ }
+
+ const root = document.createElement('div')
+ root.innerHTML = await renderToString(h(App))
+ createSSRApp(App).mount(root)
+ expect(root.innerHTML).toBe('foo
')
+
+ reload(appId, {
+ __hmrId: appId,
+ template: `bar
`,
+ })
+ await nextTick()
+ expect(root.innerHTML).toBe('bar
')
+ })
+
describe('mismatch handling', () => {
test('text node', () => {
const { container } = mountWithHydration(`foo`, () => 'bar')
diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts
index 748de866f75..cba5e4ede02 100644
--- a/packages/runtime-core/src/apiCreateApp.ts
+++ b/packages/runtime-core/src/apiCreateApp.ts
@@ -383,13 +383,12 @@ export function createAppAPI(
// HMR root reload
if (__DEV__) {
context.reload = () => {
+ const cloned = cloneVNode(vnode)
+ // avoid hydration for hmr updating
+ cloned.el = null
// casting to ElementNamespace because TS doesn't guarantee type narrowing
// over function boundaries
- render(
- cloneVNode(vnode),
- rootContainer,
- namespace as ElementNamespace,
- )
+ render(cloned, rootContainer, namespace as ElementNamespace)
}
}