diff --git a/docs/2.guide/2.directory-structure/1.components.md b/docs/2.guide/2.directory-structure/1.components.md index 655cb98bd9..1addc266c2 100644 --- a/docs/2.guide/2.directory-structure/1.components.md +++ b/docs/2.guide/2.directory-structure/1.components.md @@ -318,7 +318,7 @@ You can partially hydrate a component by setting a `nuxt-client` attribute on th ``` ::alert{type=info} -This only works within a server component. Slots for client components are not available yet. +This only works within a server component. Slots for client components are working only with `experimental.componentIsland.selectiveClient` set to `'deep'` and since they are rendered server-side, they are not interactive once client-side. :: #### Server Component Context diff --git a/packages/nuxt/src/app/components/nuxt-island.ts b/packages/nuxt/src/app/components/nuxt-island.ts index f1a6e20005..7191dcf747 100644 --- a/packages/nuxt/src/app/components/nuxt-island.ts +++ b/packages/nuxt/src/app/components/nuxt-island.ts @@ -260,20 +260,24 @@ export default defineComponent({ } if (import.meta.server) { for (const [id, info] of Object.entries(payloads.components ?? {})) { - const { html } = info + const { html, slots } = info + let replaced = html.replaceAll('data-island-uid', `data-island-uid="${uid.value}"`) + for (const slot in slots) { + replaced = replaced.replaceAll(`data-island-slot="${slot}">`, (full) => full + slots[slot]) + } teleports.push(createVNode(Teleport, { to: `uid=${uid.value};client=${id}` }, { - default: () => [createStaticVNode(html, 1)] + default: () => [createStaticVNode(replaced, 1)] })) } - } - if (selectiveClient && import.meta.client && canLoadClientComponent.value) { + } else if (selectiveClient && import.meta.client && canLoadClientComponent.value) { for (const [id, info] of Object.entries(payloads.components ?? {})) { - const { props } = info + const { props, slots } = info const component = components!.get(id)! // use different selectors for even and odd teleportKey to force trigger the teleport const vnode = createVNode(Teleport, { to: `${isKeyOdd ? 'div' : ''}[data-island-uid='${uid.value}'][data-island-component="${id}"]` }, { default: () => { - return [h(component, props)] + return [h(component, props, Object.fromEntries(Object.entries(slots || {}).map(([k, v]) => ([k, () => createStaticVNode(`
count: 0
This component should not be preloadedcount: 0
This component should not be preloadedcount: 0
This component should not be preloadedcount: 0
This component should not be preloadedhello world !!!
hello world !!!