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);
});
});