nuxt
nuxt copied to clipboard
support client interactivity within server components
Describe the feature
Right now, you can't have client components as children of server components, but enabling this would enable a bunch of usful usecases.
for example I have a big website using nuxt, with mostly static content but also bit of interactive content (like accordions or toggles to hide and show content). Server components would allow me to not send the JS for most of my site to the client, greatly reducing time spend on script parsing and execution (hydration), but right now that would disallow me from using any interactive elements. (for reference, next.js supports this: https://beta.nextjs.org/docs/rendering/server-and-client-components#moving-client-components-to-the-leaves)
I would imagine that the easiest way would be to enable server components to have slots and in the client somehow check if there is a client component slot present in the server component html. Maybe NuxtServerComponent needs to parse the html to find out where to inject the slots or we can store that info in the island response.
I have a bunch of work time next week to dedicate to working on this, but I dont really know where to start, if anybody has any pointers where I can look or what the best approach would be, that would be appreciated, I am MiniDigger#3086 on discord.
Additional information
- [X] Would you be willing to help implement this feature?
- [ ] Could this feature be implemented as a module?
Final checks
- [X] Read the contribution guide.
- [X] Check existing discussions and issues.
Yes, this is absolutely on our roadmap (created https://github.com/nuxt/nuxt/issues/19772 to track). I was talking to @huang-julien this morning who was talking about working on this as well.
For what it's worth, my recommendation is that we render keyed elements for slots with unique IDs and then use <Teleport>
to fill them with interactive content on client-side. There may be other implementation ideas you might have.
Hi ! I did take a look at how next was implementing this this week, I was planning to start working on this this weekend 🙂.
Not sure if using Teleport
would work but I think we can give it a try. Another way is to completly control the SSR render mechanism with createBuffer()
used by NuxtClientFallback
and use Teleport
only client-side.
Feel free to ping me on discord !
glad to year that, you are prolly much more qualified for that, this was my first time poking so deep into nuxt. I already managed to play around a bit today (forgot to commit my stuff somewhere, but I basically was trying to get slots working by serializing them (the name and the props of all children in the slot) and passing them to the server just like its done with props, my approach required globally registered components), but didn't get to interactivity.
one thing I lost a few hairs over is that this replace is too greedy when you have multiple comments, adding a ? after the * fixed stuff for me, in case that can save you some time https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/runtime/nitro/renderer.ts#L321
I'm not much more qualified than you, i believe everyone can make its own contribution to anything 🙂 (especially to nuxt ! 😃 )
The usage of teleport for rendering server component is going to be removed (with https://github.com/nuxt/nuxt/pull/19605 ) as this would allow us to have async component. I think controlling enterely the server side rendering would allow set uids for client-side Teleport
.