diff --git a/src/diff/index.js b/src/diff/index.js index 57f1512ad6..3ef43bfffb 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -555,7 +555,11 @@ function diffElementNodes( ); // Remove children that are not part of any vnode. - if (excessDomChildren != NULL) { + if ( + excessDomChildren != NULL && + newVNode.type != 'body' && + newVNode.type != 'head' + ) { for (i = excessDomChildren.length; i--; ) { removeNode(excessDomChildren[i]); } diff --git a/test/browser/hydrate.test.js b/test/browser/hydrate.test.js index 7a6370ed68..408776a6b4 100644 --- a/test/browser/hydrate.test.js +++ b/test/browser/hydrate.test.js @@ -485,6 +485,33 @@ describe('hydrate()', () => { expect(getLog()).to.deep.equal(['Comment.remove()', 'Comment.remove()']); }); + it('should preserve existing head children when hydrating document', () => { + document.textContent = ''; + document.head.innerHTML = + '
Test
'; + clearLog(); + + const App = () => ( +Test
+ +Test
'); + }); + it('should work with error boundaries', () => { scratch.innerHTML = 'Test
' - ); + expect(document.head.querySelector('title').textContent).to.equal('Test'); + expect(document.body.innerHTML.trim()).to.equal('Test
'); }); it('should not remount components when replacing a component with a falsy value in-between', () => {