svelte icon indicating copy to clipboard operation
svelte copied to clipboard

Svelte 5 next.179+: SSR regression with web components

Open sukeshpabolu opened this issue 1 year ago • 15 comments

Describe the bug

Facing Uncaught (in promise) HierarchyRequestError: Failed to execute 'appendChild' on 'Node': This node type does not support this method. when style element is included as first child of custom element

Reproduction

here

Logs

Uncaught (in promise) HierarchyRequestError: Failed to execute 'appendChild' on 'Node': This node type does not support this method.

System Info

stackblitz 
System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    svelte: 5.0.0-next.178 => 5.0.0-next.178

Severity

blocking an upgrade

sukeshpabolu avatar Sep 04 '24 19:09 sukeshpabolu

One thing we could do here is detect a custom-element as the parent at compile time and insert different DOM traversal methods that allow for things like <style> elements that might occur between.

trueadm avatar Sep 04 '24 19:09 trueadm

There also have been issues with web components + hydration in Svelte 4, where attributes were adjusted before the hydration came across it. It's definetly a tricky area, and something where a bit more robustness/"leave it alone" wouldn't hurt.

dummdidumm avatar Sep 04 '24 19:09 dummdidumm

I'm testing this a bit and it doesn't seem to ever worked in any version of svelte 5, it's throwing some version of this hydration error since the beginning.

paoloricciuti avatar Sep 04 '24 19:09 paoloricciuti

Sound about right - would've been surprised that this ever worked. Giving this the 5.x milestone, but if someone wants to fix it before 5.0 they're welcome to.

dummdidumm avatar Sep 04 '24 19:09 dummdidumm

I'm testing this a bit and it doesn't seem to ever worked in any version of svelte 5, it's throwing some version of this hydration error since the beginning.

It worked in 178. If you can suggest a temp fix that will be good atleast

SukeshP1995 avatar Sep 04 '24 19:09 SukeshP1995

I'm testing this a bit and it doesn't seem to ever worked in any version of svelte 5, it's throwing some version of this hydration error since the beginning.

It worked in 178. If you can suggest a temp fix that will be good atleast

image

This is in your reproduction, installing [email protected]...as you can see the error about hydration is still there. Did it behave differently than the latest versions?

paoloricciuti avatar Sep 04 '24 20:09 paoloricciuti

Ok now i think i get what you are saying @SukeshP1995 ...after 179 the whole app goes blank, before it was showing. The problem however is that your custom element is still not hydrated properly so whatever svelte code is inside or even after your custom element will not work properly.

paoloricciuti avatar Sep 04 '24 20:09 paoloricciuti

I'm testing this a bit and it doesn't seem to ever worked in any version of svelte 5, it's throwing some version of this hydration error since the beginning.

It worked in 178. If you can suggest a temp fix that will be good atleast

Speaking of this i have to admit i never actually worked extensively with web components but if i can have an intuition about what you are trying to do with lightStyleCss is to add some css for the light dom right? If so this doesn't cause hydration issues even in the latest version of svelte

connectedCallback() {
  const lightStyles = document.createElement('style');
  lightStyles.slot = 'light-styles';
  lightStyles.innerHTML = lightStyleSheet;
-  this.append(lightStyles.cloneNode(true));
+  document.head.append(lightStyles.cloneNode(true));
}

but again i don't know if this is feasible

paoloricciuti avatar Sep 04 '24 20:09 paoloricciuti

I still believe my post above should resolve this.

trueadm avatar Sep 04 '24 22:09 trueadm

I still believe my post above should resolve this.

Hi, the web components are in a package (private). If it had been my own I would have found a different way to inject those styles

SukeshP1995 avatar Sep 05 '24 05:09 SukeshP1995

I'm testing this a bit and it doesn't seem to ever worked in any version of svelte 5, it's throwing some version of this hydration error since the beginning.

It worked in 178. If you can suggest a temp fix that will be good atleast

Speaking of this i have to admit i never actually worked extensively with web components but if i can have an intuition about what you are trying to do with lightStyleCss is to add some css for the light dom right? If so this doesn't cause hydration issues even in the latest version of svelte


connectedCallback() {

  const lightStyles = document.createElement('style');

  lightStyles.slot = 'light-styles';

  lightStyles.innerHTML = lightStyleSheet;

-  this.append(lightStyles.cloneNode(true));

+  document.head.append(lightStyles.cloneNode(true));

}

but again i don't know if this is feasible

I will try this and see, but FYI the web components are in a seperate internal package so I have to patch those then

SukeshP1995 avatar Sep 05 '24 05:09 SukeshP1995

I will try this and see, but FYI the web components are in a seperate internal package so I have to patch those then

Yeah i've imagined that...unfortunately hydration requires the order of elements to be consistent between SSR and the hydration phase...we can see if we can implement what Dominic proposed but until then you might need to find ways around it. :(

paoloricciuti avatar Sep 05 '24 08:09 paoloricciuti

I will try this and see, but FYI the web components are in a seperate internal package so I have to patch those then

Yeah i've imagined that...unfortunately hydration requires the order of elements to be consistent between SSR and the hydration phase...we can see if we can implement what Dominic proposed but until then you might need to find ways around it. :(

I started pnpm patching my web components 😩. (they are only 4 of them)

sukeshpabolu avatar Sep 05 '24 08:09 sukeshpabolu

What about adoptedStyleSheets? It inserts styles without creating a node in the DOM.

  connectedCallback() {
    const sheet = new CSSStyleSheet();
    sheet.replaceSync(lightStyleSheet);
    // add styles to the closest shadowRoot or document
    this.getRootNode().adoptedStyleSheets = [sheet];
  }

It's even recommended to hoist sheet to re-use it.

7nik avatar Sep 05 '24 09:09 7nik

Every time I use the component it is creating the style tag. I am having a bunch of style tags now 🤣

SukeshP1995 avatar Sep 05 '24 16:09 SukeshP1995