summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Arsh <69170106+lilnasy@users.noreply.github.com> 2024-03-07 21:55:03 +0530
committerGravatar GitHub <noreply@github.com> 2024-03-07 21:55:03 +0530
commit33583e8b31ee8a33e26cf57f30bb422921f4745d (patch)
tree50bb26945f7567fda60d84ba02a6d469efd7180f
parent3de48e8f62c7ddd2bdfcde9d485908ddaa55c8cf (diff)
downloadastro-33583e8b31ee8a33e26cf57f30bb422921f4745d.tar.gz
astro-33583e8b31ee8a33e26cf57f30bb422921f4745d.tar.zst
astro-33583e8b31ee8a33e26cf57f30bb422921f4745d.zip
fix(rendering): prevent removal of necessary `<astro-slot>` elements (#10317)
* fix(rendering): prevent removal of necessary `<astro-slot>` elements * add test * add changeset * missed a spot * adjust test * assume `supportsAstroStaticSlot` * bring back accidentally removed `markHTMLString` call
-rw-r--r--.changeset/thick-geckos-design.md5
-rw-r--r--packages/astro/e2e/fixtures/svelte-component/src/components/Poly.astro6
-rw-r--r--packages/astro/e2e/fixtures/svelte-component/src/components/Stuff.svelte4
-rw-r--r--packages/astro/e2e/fixtures/svelte-component/src/pages/with-slots.astro23
-rw-r--r--packages/astro/e2e/svelte-component.test.js11
-rw-r--r--packages/astro/src/runtime/server/render/component.ts8
-rw-r--r--packages/astro/test/astro-slot-with-client.test.js4
7 files changed, 56 insertions, 5 deletions
diff --git a/.changeset/thick-geckos-design.md b/.changeset/thick-geckos-design.md
new file mode 100644
index 000000000..28568f01e
--- /dev/null
+++ b/.changeset/thick-geckos-design.md
@@ -0,0 +1,5 @@
+---
+"astro": patch
+---
+
+Fixes an issue where elements slotted within interactive framework components disappeared after hydration.
diff --git a/packages/astro/e2e/fixtures/svelte-component/src/components/Poly.astro b/packages/astro/e2e/fixtures/svelte-component/src/components/Poly.astro
new file mode 100644
index 000000000..9f6a0cf11
--- /dev/null
+++ b/packages/astro/e2e/fixtures/svelte-component/src/components/Poly.astro
@@ -0,0 +1,6 @@
+---
+const Tag = 'div';
+---
+<Tag>
+ <slot />
+</Tag>
diff --git a/packages/astro/e2e/fixtures/svelte-component/src/components/Stuff.svelte b/packages/astro/e2e/fixtures/svelte-component/src/components/Stuff.svelte
new file mode 100644
index 000000000..9d7f1d4e0
--- /dev/null
+++ b/packages/astro/e2e/fixtures/svelte-component/src/components/Stuff.svelte
@@ -0,0 +1,4 @@
+<script>
+ export let id;
+</script>
+<div {id}>Slot goes here:<slot /></div>
diff --git a/packages/astro/e2e/fixtures/svelte-component/src/pages/with-slots.astro b/packages/astro/e2e/fixtures/svelte-component/src/pages/with-slots.astro
new file mode 100644
index 000000000..43ce8a63a
--- /dev/null
+++ b/packages/astro/e2e/fixtures/svelte-component/src/pages/with-slots.astro
@@ -0,0 +1,23 @@
+---
+import Poly from '../components/Poly.astro';
+import Stuff from '../components/Stuff.svelte';
+---
+
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width" />
+ <title>Astro</title>
+ </head>
+ <body>
+ <h1>Astro</h1>
+
+ <Poly>
+ <Stuff client:load id="hydratable">poo</Stuff>
+ </Poly>
+
+ <Poly>
+ <Stuff id="ssr-only">bar</Stuff>
+ </Poly>
+ </body>
+</html>
diff --git a/packages/astro/e2e/svelte-component.test.js b/packages/astro/e2e/svelte-component.test.js
index f0c9aa9bc..67e032474 100644
--- a/packages/astro/e2e/svelte-component.test.js
+++ b/packages/astro/e2e/svelte-component.test.js
@@ -1,5 +1,6 @@
import { expect } from '@playwright/test';
import { prepareTestFactory } from './shared-component-tests.js';
+import { waitForHydrate } from './test-utils.js';
const { test, createTests } = prepareTestFactory({ root: './fixtures/svelte-component/' });
@@ -35,3 +36,13 @@ test.describe('Svelte components lifecycle', () => {
expect((await toggle.textContent()).trim()).toBe('open');
});
});
+
+
+test.describe('Slotting content into svelte components', () => {
+ test('should stay after hydration', async ({ page, astro }) => {
+ await page.goto(astro.resolveUrl('/with-slots'));
+ const hydratableElement = page.locator('#hydratable');
+ await waitForHydrate(page, hydratableElement);
+ await expect(hydratableElement).toHaveText("Slot goes here:poo");
+ });
+});
diff --git a/packages/astro/src/runtime/server/render/component.ts b/packages/astro/src/runtime/server/render/component.ts
index 5d3435126..1d6b6e6dd 100644
--- a/packages/astro/src/runtime/server/render/component.ts
+++ b/packages/astro/src/runtime/server/render/component.ts
@@ -67,7 +67,8 @@ function isHTMLComponent(Component: unknown) {
const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g;
const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g;
-function removeStaticAstroSlot(html: string, supportsAstroStaticSlot: boolean) {
+
+function removeStaticAstroSlot(html: string, supportsAstroStaticSlot = true) {
const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP;
return html.replace(exp, '');
}
@@ -310,7 +311,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
} else if (html && html.length > 0) {
destination.write(
markHTMLString(
- removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot ?? false)
+ removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot)
)
);
}
@@ -391,7 +392,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
})
);
}
- destination.write(markHTMLString(renderElement('astro-island', island, false)));
+ const renderedElement = renderElement('astro-island', island, false);
+ destination.write(markHTMLString(renderedElement));
},
};
}
diff --git a/packages/astro/test/astro-slot-with-client.test.js b/packages/astro/test/astro-slot-with-client.test.js
index a52d9b907..8f34b8fc9 100644
--- a/packages/astro/test/astro-slot-with-client.test.js
+++ b/packages/astro/test/astro-slot-with-client.test.js
@@ -18,9 +18,9 @@ describe('Slots with client: directives', () => {
assert.equal($('script').length, 1);
});
- it('Astro slot tags are cleaned', async () => {
+ it('Astro slot tags are kept', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerio.load(html);
- assert.equal($('astro-slot').length, 0);
+ assert.equal($('astro-slot').length, 1);
});
});