diff options
-rw-r--r-- | .changeset/deep-mammals-watch.md | 6 | ||||
-rw-r--r-- | packages/astro/e2e/client-only.test.js | 16 | ||||
-rw-r--r-- | packages/astro/e2e/fixtures/client-only/src/pages/index.astro | 5 | ||||
-rw-r--r-- | packages/integrations/preact/src/client.ts | 16 | ||||
-rw-r--r-- | packages/integrations/svelte/client.svelte.js | 3 |
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) { |