summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/deep-mammals-watch.md6
-rw-r--r--packages/astro/e2e/client-only.test.js16
-rw-r--r--packages/astro/e2e/fixtures/client-only/src/pages/index.astro5
-rw-r--r--packages/integrations/preact/src/client.ts16
-rw-r--r--packages/integrations/svelte/client.svelte.js3
5 files changed, 41 insertions, 5 deletions
diff --git a/.changeset/deep-mammals-watch.md b/.changeset/deep-mammals-watch.md
new file mode 100644
index 000000000..79db0e354
--- /dev/null
+++ b/.changeset/deep-mammals-watch.md
@@ -0,0 +1,6 @@
+---
+'@astrojs/preact': patch
+'@astrojs/svelte': patch
+---
+
+Hides fallback content when rendering `client:only` island
diff --git a/packages/astro/e2e/client-only.test.js b/packages/astro/e2e/client-only.test.js
index 62a05f8dc..fc4316e8d 100644
--- a/packages/astro/e2e/client-only.test.js
+++ b/packages/astro/e2e/client-only.test.js
@@ -20,6 +20,9 @@ test.describe('Client only', () => {
const counter = await page.locator('#react-counter');
await expect(counter, 'component is visible').toBeVisible();
+ const fallback = await page.locator('[data-fallback=react]');
+ await expect(fallback, 'fallback content is hidden').not.toBeVisible();
+
const count = await counter.locator('pre');
await expect(count, 'initial count is 0').toHaveText('0');
@@ -38,6 +41,10 @@ test.describe('Client only', () => {
const counter = await page.locator('#preact-counter');
await expect(counter, 'component is visible').toBeVisible();
+
+ const fallback = await page.locator('[data-fallback=preact]');
+ await expect(fallback, 'fallback content is hidden').not.toBeVisible();
+
const count = await counter.locator('pre');
await expect(count, 'initial count is 0').toHaveText('0');
@@ -56,6 +63,9 @@ test.describe('Client only', () => {
const counter = await page.locator('#solid-counter');
await expect(counter, 'component is visible').toBeVisible();
+ const fallback = await page.locator('[data-fallback=solid]');
+ await expect(fallback, 'fallback content is hidden').not.toBeVisible();
+
const count = await counter.locator('pre');
await expect(count, 'initial count is 0').toHaveText('0');
@@ -74,6 +84,9 @@ test.describe('Client only', () => {
const counter = await page.locator('#vue-counter');
await expect(counter, 'component is visible').toBeVisible();
+ const fallback = await page.locator('[data-fallback=vue]');
+ await expect(fallback, 'fallback content is hidden').not.toBeVisible();
+
const count = await counter.locator('pre');
await expect(count, 'initial count is 0').toHaveText('0');
@@ -92,6 +105,9 @@ test.describe('Client only', () => {
const counter = await page.locator('#svelte-counter');
await expect(counter, 'component is visible').toBeVisible();
+ const fallback = await page.locator('[data-fallback=svelte]');
+ await expect(fallback, 'fallback content is hidden').not.toBeVisible();
+
const count = await counter.locator('pre');
await expect(count, 'initial count is 0').toHaveText('0');
diff --git a/packages/astro/e2e/fixtures/client-only/src/pages/index.astro b/packages/astro/e2e/fixtures/client-only/src/pages/index.astro
index a80bddc0e..003636e17 100644
--- a/packages/astro/e2e/fixtures/client-only/src/pages/index.astro
+++ b/packages/astro/e2e/fixtures/client-only/src/pages/index.astro
@@ -19,22 +19,27 @@ import VueCounter from '../components/vue/VueCounter.vue';
<main>
<react.Counter id="react-counter" client:only="react">
<h1>react</h1>
+ <p slot="fallback" data-fallback="react">Loading React...</p>
</react.Counter>
<PreactCounter id="preact-counter" client:only="preact">
<h1>preact</h1>
+ <p slot="fallback" data-fallback="preact">Loading Preact...</p>
</PreactCounter>
<SolidCounter id="solid-counter" client:only="solid-js">
<h1>solid</h1>
+ <p slot="fallback" data-fallback="solid">Loading Solid...</p>
</SolidCounter>
<VueCounter id="vue-counter" client:only="vue">
<h1>vue</h1>
+ <p slot="fallback" data-fallback="vue">Loading Vue...</p>
</VueCounter>
<SvelteCounter id="svelte-counter" client:only="svelte">
<h1>svelte</h1>
+ <p slot="fallback" data-fallback="svelte">Loading Svelte...</p>
</SvelteCounter>
</main>
</body>
diff --git a/packages/integrations/preact/src/client.ts b/packages/integrations/preact/src/client.ts
index 32fdc9888..40475acc8 100644
--- a/packages/integrations/preact/src/client.ts
+++ b/packages/integrations/preact/src/client.ts
@@ -49,13 +49,19 @@ export default (element: HTMLElement) =>
}
}
- const bootstrap = client !== 'only' ? hydrate : render;
-
- bootstrap(
- h(Component, props, children != null ? h(StaticHtml, { value: children }) : children),
- element,
+ const child = h(
+ Component,
+ props,
+ children != null ? h(StaticHtml, { value: children }) : children,
);
+ if (client === 'only') {
+ element.innerHTML = '';
+ render(child, element);
+ } else {
+ hydrate(child, element);
+ }
+
// Preact has no "unmount" option, but you can use `render(null, element)`
element.addEventListener('astro:unmount', () => render(null, element), { once: true });
};
diff --git a/packages/integrations/svelte/client.svelte.js b/packages/integrations/svelte/client.svelte.js
index 4f861e96d..85a2cd890 100644
--- a/packages/integrations/svelte/client.svelte.js
+++ b/packages/integrations/svelte/client.svelte.js
@@ -61,6 +61,9 @@ export default (element) => {
function createComponent(Component, target, props, shouldHydrate) {
let propsState = $state(props);
const bootstrap = shouldHydrate ? hydrate : mount;
+ if(!shouldHydrate) {
+ target.innerHTML = '';
+ }
const component = bootstrap(Component, { target, props: propsState });
return {
setProps(newProps) {