diff --git a/.changeset/ten-rice-unite.md b/.changeset/ten-rice-unite.md new file mode 100644 index 0000000000..9ae22d6529 --- /dev/null +++ b/.changeset/ten-rice-unite.md @@ -0,0 +1,6 @@ +--- +"@astrojs/solid-js": patch +"@astrojs/renderer-solid": patch +--- + +Improve nested hydration with Solid diff --git a/packages/integrations/solid/client.js b/packages/integrations/solid/client.js index b67b3acdb7..4424e9b985 100644 --- a/packages/integrations/solid/client.js +++ b/packages/integrations/solid/client.js @@ -1,14 +1,25 @@ +import { sharedConfig } from 'solid-js'; import { hydrate, createComponent } from 'solid-js/web'; export default (element) => (Component, props, childHTML) => { let children; - if (childHTML != null) { - children = document.createElement('astro-fragment'); - children.innerHTML = childHTML; - } + hydrate( + () => + createComponent(Component, { + ...props, + get children() { + if (childHTML != null) { + // hydrating + if (sharedConfig.context) children = element.querySelector('astro-fragment'); - // Using Solid's `hydrate` method ensures that a `root` is created - // in order to properly handle reactivity. It also handles - // components that are not native HTML elements. - hydrate(() => createComponent(Component, { ...props, children }), element); + if (children == null) { + children = document.createElement('astro-fragment'); + children.innerHTML = childHTML; + } + } + return children; + }, + }), + element + ); }; diff --git a/packages/renderers/renderer-solid/client.js b/packages/renderers/renderer-solid/client.js index b67b3acdb7..4424e9b985 100644 --- a/packages/renderers/renderer-solid/client.js +++ b/packages/renderers/renderer-solid/client.js @@ -1,14 +1,25 @@ +import { sharedConfig } from 'solid-js'; import { hydrate, createComponent } from 'solid-js/web'; export default (element) => (Component, props, childHTML) => { let children; - if (childHTML != null) { - children = document.createElement('astro-fragment'); - children.innerHTML = childHTML; - } + hydrate( + () => + createComponent(Component, { + ...props, + get children() { + if (childHTML != null) { + // hydrating + if (sharedConfig.context) children = element.querySelector('astro-fragment'); - // Using Solid's `hydrate` method ensures that a `root` is created - // in order to properly handle reactivity. It also handles - // components that are not native HTML elements. - hydrate(() => createComponent(Component, { ...props, children }), element); + if (children == null) { + children = document.createElement('astro-fragment'); + children.innerHTML = childHTML; + } + } + return children; + }, + }), + element + ); };