nuxt icon indicating copy to clipboard operation
nuxt copied to clipboard

support client interactivity within server components

Open MiniDigger opened this issue 1 year ago • 4 comments

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

MiniDigger avatar Mar 17 '23 12:03 MiniDigger

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.

danielroe avatar Mar 17 '23 15:03 danielroe

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 !

huang-julien avatar Mar 17 '23 15:03 huang-julien

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

MiniDigger avatar Mar 17 '23 17:03 MiniDigger

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 .

huang-julien avatar Mar 17 '23 17:03 huang-julien