Skip to content

Can't replace top-level HTML element when hydrating #5547

@jimafisk

Description

@jimafisk

Describe the bug
If you try to replace the <html> wrapper during hydration, it throws errors on line 179 of svelte/internal/index.mjs because it can't insertBefore the top-level document. I'm trying to use an entrypoint in this format:

new App({                
  target: document,
  hydrate: true
});

Logs

  • Chrome: DOMException: Failed to execute 'insertBefore' on 'Node': Only one element on document allowed.
  • Firefox: DOMException: Node.insertBefore: Cannot have more than one Element child of a Document

To Reproduce
Unfortunately I don't think I can use the repl to demonstrate hydration issues. This can be seen in the default starter of https://github.com/plentico/plenti. EDIT: Added a demo that doesn't require plenti: https://github.com/jimafisk/svelte-document-replace

Expected behavior
I'd like to be able to use the top-level document as a target without hitting errors. I'm not sure the exact fix to minimize negative impact on other aspects of svelte would be, but a temp fix on line 178 of node_modules/svelte/internal/index.mjs works for me:

function insert(target, node, anchor) {       
  if (target != document) {
    target.insertBefore(node, anchor || null);
  }
}

Stacktraces
N/A

Information about your Svelte project:

  • Your browser and the version:
    • Chrome Version 85.0.4183.102 (Official Build) (64-bit)
    • Firefox Version 81.0 (64-bit)
  • Your operating system: Ubuntu Linux 18.04 LTS
  • Svelte version: 3.23.2
  • Whether your project uses Webpack or Rollup: N/A, I'm using ESM imports

Severity
I currently have to tweak the Svelte lib to make it work with my project, but I recognize that we have a small userbase and there are higher priority items.

Additional context
The error message is the same as shown here, although that seems to be related to a slightly different issue.

Here's another conversation about replacing top-level elements during hydration: https://stackoverflow.com/questions/61640429/how-to-replace-the-contents-of-a-target-in-svelte-instead-of-appending-to-childr

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions