framework icon indicating copy to clipboard operation
framework copied to clipboard

feat(nuxt): server component islands

Open danielroe opened this issue 2 years ago β€’ 14 comments

πŸ”— Linked issue

  • Implements: https://github.com/nuxt/framework/discussions/666

❓ Type of change

  • [ ] πŸ“– Documentation (updates to the documentation or readme)
  • [ ] 🐞 Bug fix (a non-breaking change that fixes an issue)
  • [ ] πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • [x] ✨ New feature (a non-breaking change that adds functionality)
  • [ ] ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

This PR adds support for rendering individual components through a special GET request to /__nuxt_render (implementing RFC https://github.com/nuxt/framework/discussions/666).

In addition to providing the basis for server-only components (https://github.com/nuxt/framework/pull/5688) it can also provide a way to render individual components for future testing or devtools functionality.

Note that this only supports components that are already globally registered in the server.

If you encounter any issues with rendering async components in this way, please also see https://github.com/vuejs/core/issues/6207.

πŸ“ Checklist

  • [x] I have linked an issue or discussion.
  • [ ] I have updated the documentation accordingly.

danielroe avatar Jul 01 '22 10:07 danielroe

Deploy Preview for nuxt3-docs canceled.

Name Link
Latest commit 2484081c6300754cba5c571613469c1cd2ebeb4d
Latest deploy log https://app.netlify.com/sites/nuxt3-docs/deploys/636e472d26f7980008784de0

netlify[bot] avatar Jul 01 '22 10:07 netlify[bot]

FYI: I'll be refactoring this to support only explicit island components rather than any global components. That change is pending merge of https://github.com/nuxt/framework/pull/6070.

danielroe avatar Jul 25 '22 13:07 danielroe

To improve caching possibilities and isolation, I've made some refactors. New /__nuxt_island endpoint accepts name (required), props and format queries and returns constructed HTML object with only different that rendered body, is (teleported) island component. This way we can apply same render:html transform hooks.

Example endpoints (working with yarn nuxt dev test/fixtures/basic)

  • http://localhost:3000/__nuxt_island/PureComponent
  • http://localhost:3000/__nuxt_island/PureComponent:hash?props={}

pi0 avatar Aug 17 '22 18:08 pi0

My main worry is that this PR was meant to focus on the rendering side of things and leave the discussion of component implementation to https://github.com/nuxt/framework/pull/5688.

Server-only components proposed in nuxt/framework#5688 are a really nice addition to build on top of component islands API and looking forward to it πŸ”₯

Islands API not only allows implementing server-only components but also being able to fetch components from remote sources in runtime (not same server) and more possibilities for testing, playground, etc. So I think <NuxtIsland> is more relevant to the scope of initial PR. We could try different ideas and improvements in parallel. Originally referred to this as selective-rendering/isolated-rendering in my RFC and with intention of making an external library to be integrated with Nuxt but adding to nuxt became more straightforward. Last changes are closer to what I had in mind and hope compatible with server-only components impl.

pi0 avatar Aug 18 '22 13:08 pi0

@pi0 Just want to check in on this. What are the next steps in the path to merging this PR? Is there anything I can do?

danielroe avatar Aug 24 '22 09:08 danielroe

Working inlined styles (https://github.com/nuxt/nuxt.js/issues/14653) to have a working MVP.

pi0 avatar Aug 24 '22 09:08 pi0

nuxt/nuxt.js#14653 Merged 😏

Sunhat avatar Sep 26 '22 08:09 Sunhat

@pi0 What do you think about merging in behind an experimental flag?

danielroe avatar Sep 26 '22 10:09 danielroe

Is it possible to update the Readme to give an example on how to use <NuxtIsland> component? Shall we start writing a page in the docs regarding the Islands component and the current state?

atinux avatar Sep 28 '22 08:09 atinux

This PR was originally meant to be just the rendering method, with https://github.com/nuxt/framework/pull/5688 to implement the actual component to render the result. <NuxtIsland /> was added to this PR, which overlaps somewhat with the server component wrapper in that PR. Once this is merged, it should be fairly quick to update that PR to implement proper server components + add documentation for <NuxtIsland />. (Or I could merge that one into this and add docs.) wdyt @Atinux?

danielroe avatar Sep 28 '22 09:09 danielroe

Tell me if I am wrong, but <NuxtIsland> is a shortcut for the endpoint to render HTML from a component right?

nuxt/framework#5688 goal is to support .server.vue suffix that will leverage <NuxtIsland> under the hood?

If so, I think we can instead merge this PR in that state and improve nuxt/framework#5688 which already has a great description!

atinux avatar Sep 28 '22 09:09 atinux

Exactly!

danielroe avatar Sep 28 '22 09:09 danielroe

@pi0 What's the status of this PR?

danielroe avatar Nov 05 '22 19:11 danielroe

Update: This PR is really in a good state and is ready to be landed as an experimental feature. I've also worked on inlined styles to be working on production (7c66c41554ecd2fca5d512a1f32c45348f7cf312) and added experimental.componentIslands flag.

Landing this feature for 3.1.0 alongside .server components. (Landing for 3.0.0 is really hard since we plan release today sorry for delays).

pi0 avatar Nov 16 '22 12:11 pi0

🫢🏻🫢🏻🫢🏻 @danielroe

josueayala27 avatar Nov 24 '22 18:11 josueayala27