Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nuxt): support basic slots on server only components #19851

Closed
wants to merge 39 commits into from

Conversation

huang-julien
Copy link
Member

@huang-julien huang-julien commented Mar 21, 2023

πŸ”— Linked issue

resolve #19765
resolve #19884

❓ Type of change

  • πŸ“– Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Hi πŸ‘‹

This PR is currently in progress (draft to keep tracking my progress on it)

  • PR done and ready

This PR allow to have slots with server only components.

Slots also works in SSR for pages !

Currently the only way to simulate a slot is to render a container tag, however it needs a display: contents which seems just a bit buggy atm in some cases but we still need it to ignore the container tag box, maybe will it be fixed one day.
see: https://caniuse.com/css-display-contents

How does this work ?

This introduce changes to <NuxtIsland>, <IslandRenderer>, server components and to the nitro renderer./

  • server only components:
    • it now becomes a wrapper to call NuxtIsland
  • <NuxtIsland>
    • each calls to the islandRenderer are now unique
    • it bypass its hydration
    • teleport all its slots to the slot containers rendered by IslandRenderer
  • IslandRenderer
    • render the component with an UID in its attributes
    • now receive a list of slots (only names) to render a container tag for NuxtIsland to teleport its slots

πŸ“ Checklist and TODO

related to the branch

  • clean the messy code

related to PR

  • I have linked an issue or discussion.
  • fix prod/build
  • use uncrypto
  • improve perf for SSR renderer (don't try to replace if there's no v-ssr-component-uid or v-ssr-slot-name)
  • I have updated the documentation
  • update docs about limitations (container tag for now, slots can't be conditional, scoped slots not available yet)
  • complete fixtures tests

fixtures

  • test nuxt islands
  • test .server
  • test slot interactivity
  • test slot with server components mounted Post SSR

@codesandbox
Copy link

codesandbox bot commented Mar 21, 2023

CodeSandbox logoCodeSandbox logoΒ  Open in CodeSandbox Web Editor | VS Code | VS Code Insiders

@huang-julien
Copy link
Member Author

huang-julien commented Mar 26, 2023

ATM this PR is only working in dev mode.

However #19911 which fixes the server only components re-rendering (by using a key to force the static vnode to re-render) introduce another issue (in build).
Since this PR use Teleport, re-rendering the static slot makes all slots disapear, most probably because Teleport are still being attached to the old static node. if we try to force re-render the Teleport, this won't work either because at the moment vue tries to Teleport the target node is not available yet in the DOM

The current Implementation of NextJS (did not dig too much into it) does not allow client-side interactivity.
Maybe should we do the same thing ? This would allow to have a mix of non interactive static nodes AND fully insteractive slots.

Or maybe using a allow-slot prop that would enable the usage of slots (but disabling re-rendering the server only component) ?

Edit: found a fix πŸŽ‰ πŸŽ‰

@nuxt-studio-dev
Copy link

βœ… Live Preview ready!

Name Edit Preview Latest Commit
nuxt Edit on Studio β†—οΈŽ View Live Preview 089a545

@huang-julien huang-julien marked this pull request as ready for review March 30, 2023 22:52
@danielroe danielroe added this to the v3.4 milestone Mar 31, 2023
@MiniDigger
Copy link
Contributor

MiniDigger commented Apr 1, 2023

this is absolutely awesome! πŸŽ‰

played around with the branch a bit today and it works as I would expect it to work.
one current limitation (that I dont care about rn but should prolly be documented, or maybe its just a bug?) is that slot props dont seem to work for me (the slot prop is just undefined)
similarly, conditional slots (v-if on the slot) dont seem to work (something breaks with the teleport)
for reference, here is the code: https://paste.gg/p/anonymous/c516b3a47b564a088c1f3e9911e193b8

but since server components are experimental anyways, this is a major improvement and such limitations can be addressed incrementally in the future

I dont understand exactly what you mean with the mention of display contents in the description, could you elaborate on that?
ok nvm am stupid, you use it to "hide" the added div.

@huang-julien
Copy link
Member Author

huang-julien commented Apr 2, 2023

Thank you !
In the first commits, slots containers were generated by using the __asyncResolved property which is a vue internal API (and it seems to be only working in dev), since we should avoid using vue internals the solution was to send the declared slots when updating the component. I'll check if there's a way to workaround this

About scoped slots, i think this can be done. I'll do something about it in the incoming week (won't have a lot of time) with another PR

I'll update the docs about theses limitations.

@danielroe danielroe mentioned this pull request Apr 10, 2023
@huang-julien huang-julien changed the title feat(nuxt): support slots on server only components feat(nuxt): support basic slots on server only components Apr 14, 2023
@huang-julien huang-julien marked this pull request as draft April 14, 2023 20:06
@huang-julien huang-julien marked this pull request as ready for review April 14, 2023 22:00
@danielroe danielroe modified the milestones: v3.4, v3.5 Apr 20, 2023
@huang-julien huang-julien marked this pull request as draft April 21, 2023 16:58
@huang-julien
Copy link
Member Author

I feel like this PR can be closed since #20284 includes and goes beyond this PR for slot support (since it is forked from this one)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Islands components not updating in production support client interactivity within server components
3 participants