diff --git a/packages/nuxt/src/app/components/nuxt-island.ts b/packages/nuxt/src/app/components/nuxt-island.ts
index 2d23c62b0d..24e3e16891 100644
--- a/packages/nuxt/src/app/components/nuxt-island.ts
+++ b/packages/nuxt/src/app/components/nuxt-island.ts
@@ -224,9 +224,9 @@ export default defineComponent({
watch(props, debounce(() => fetchComponent(), 100), { deep: true })
}
- if (import.meta.client && !nuxtApp.isHydrating && props.lazy) {
+ if (import.meta.client && !instance.vnode.el && props.lazy) {
fetchComponent()
- } else if (import.meta.server || !nuxtApp.isHydrating || !nuxtApp.payload.serverRendered) {
+ } else if (import.meta.server || !instance.vnode.el || !nuxtApp.payload.serverRendered) {
await fetchComponent()
} else if (selectiveClient && canLoadClientComponent.value) {
await loadComponents(props.source, payloads.components)
diff --git a/test/basic.test.ts b/test/basic.test.ts
index abaa830c4e..2603e27dc2 100644
--- a/test/basic.test.ts
+++ b/test/basic.test.ts
@@ -1530,6 +1530,9 @@ describe('server components/islands', () => {
await page.locator('#show-island').click()
expect(await page.locator('#island-mounted-client-side').innerHTML()).toContain('Interactive testing slot post SSR')
+ // test islands wrapped with client-only
+ expect(await page.locator('#wrapped-client-only').innerHTML()).toContain('Was router enabled')
+
if (!isWebpack) {
// test client component interactivity
expect(await page.locator('.interactive-component-wrapper').innerHTML()).toContain('Sugar Counter 12')
diff --git a/test/fixtures/basic/pages/islands.vue b/test/fixtures/basic/pages/islands.vue
index 45c65af8d6..4e2b59e2c2 100644
--- a/test/fixtures/basic/pages/islands.vue
+++ b/test/fixtures/basic/pages/islands.vue
@@ -20,10 +20,14 @@ const count = ref(0)
name="PureComponent"
:props="islandProps"
/>
-