diff --git a/.changeset/thick-geckos-design.md b/.changeset/thick-geckos-design.md new file mode 100644 index 000000000000..28568f01e66d --- /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 000000000000..9f6a0cf11b23 --- /dev/null +++ b/packages/astro/e2e/fixtures/svelte-component/src/components/Poly.astro @@ -0,0 +1,6 @@ +--- +const Tag = 'div'; +--- + + + 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 000000000000..9d7f1d4e0971 --- /dev/null +++ b/packages/astro/e2e/fixtures/svelte-component/src/components/Stuff.svelte @@ -0,0 +1,4 @@ + +
Slot goes here:
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 000000000000..43ce8a63aea4 --- /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'; +--- + + + + + + Astro + + +

Astro

+ + + poo + + + + bar + + + diff --git a/packages/astro/e2e/svelte-component.test.js b/packages/astro/e2e/svelte-component.test.js index f0c9aa9bc155..67e032474a70 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 5d3435126f23..1d6b6e6dd1b2 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 a52d9b907964..8f34b8fc9158 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); }); });