From c2ce09c0231ba6e806824e66b20ee8179f33971c Mon Sep 17 00:00:00 2001 From: Ryan Carniato Date: Fri, 1 Sep 2023 12:47:04 -0700 Subject: [PATCH] fix hydration in solid renderer --- .changeset/giant-cycles-marry.md | 5 ++++ packages/integrations/solid/src/client.ts | 29 +++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 .changeset/giant-cycles-marry.md diff --git a/.changeset/giant-cycles-marry.md b/.changeset/giant-cycles-marry.md new file mode 100644 index 000000000000..284f8531b5bc --- /dev/null +++ b/.changeset/giant-cycles-marry.md @@ -0,0 +1,5 @@ +--- +'@astrojs/solid-js': patch +--- + +Fix hydration in Solid renderer diff --git a/packages/integrations/solid/src/client.ts b/packages/integrations/solid/src/client.ts index 71a7db5e2e93..09c5efa3d7ac 100644 --- a/packages/integrations/solid/src/client.ts +++ b/packages/integrations/solid/src/client.ts @@ -1,4 +1,3 @@ -import { sharedConfig } from 'solid-js'; import { createComponent, hydrate, render } from 'solid-js/web'; export default (element: HTMLElement) => @@ -11,19 +10,25 @@ export default (element: HTMLElement) => const boostrap = client === 'only' ? render : hydrate; + let slot: HTMLElement | null; let _slots: Record = {}; if (Object.keys(slotted).length > 0) { - // hydrating - if (sharedConfig.context) { - element.querySelectorAll('astro-slot').forEach((slot) => { - _slots[slot.getAttribute('name') || 'default'] = slot.cloneNode(true); - }); - } else { - for (const [key, value] of Object.entries(slotted)) { - _slots[key] = document.createElement('astro-slot'); - if (key !== 'default') _slots[key].setAttribute('name', key); - _slots[key].innerHTML = value; - } + // hydratable + if (client !== "only") { + const iterator = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT, (node) => { + if (node === element) return NodeFilter.FILTER_SKIP + if (node.nodeName === "ASTRO-SLOT") return NodeFilter.FILTER_ACCEPT; + if (node.nodeName === "ASTRO-ISLAND") return NodeFilter.FILTER_REJECT; + return NodeFilter.FILTER_SKIP; + }); + while(slot = iterator.nextNode() as HTMLElement | null) + _slots[slot.getAttribute("name") || "default"] = slot; + } + for (const [key, value] of Object.entries(slotted)) { + if (_slots[key]) continue; + _slots[key] = document.createElement('astro-slot'); + if (key !== 'default') _slots[key].setAttribute('name', key); + _slots[key].innerHTML = value; } }