Search code examples
next.jsserver-sideclient-side

NextJS 13 Server Components vs Client components in complex UI


I have some doubts on overall architecture of complex, data driven UIs. Taking the usual blog page example with a sidebar, header and logo where the idea is that:

  • Header and logo are static and can be server side component
  • Sidebar is static and can be server side component
  • Footer is static and can be server side component
  • Blog posts are static and can be server side component
  • Only a search functions and a like button may be interactive and would be a client side component

In the real world, when I build this it would rather be like:

  • my sidebar is collapsible. So it has user action, it needs to show or hide depending on user choice. So I need to wrap it in a client side component that answers to a state
  • my blog posts sit inside tabs or accordion. I need to wrap my blog content in a client side component because again, content shows or hides depending on user interaction and state
  • my blog posts component will have a toggler with layout options, say between grid and list. I would need to wrap them in a client side layout component that answers to user input and state
  • my logo depends on device/window size. I need to access the window object to decide whether I want a mobile or desktop version of the logo. For this I need client side.
  • my footer has a desktop or mobile layout, I need to decide which one to load. Again, I need to access the window object or a 3rd party library that uses hooks
  • if I added a table to display data I may want to make it sortable or filterable - again content, or presentation of content, will be subject to user interaction

In the end, everything on my page is subject to some sort of user interaction or user induced state. I cannot imagine a UI I have built over the last few years that simply loads static content in an isolated manner.

The only thing that occurs to me is that for SEO I may load some data driven HTML as a skeleton via server side component so that SE Bots can read the data immediately, and then display with the interactive client side equivalent once it's ready. Not sure if that's possible using <Suspense /> I may have to do a little reading.

Otherwise, with the above use case, am I missing something? I simply can't think of a real life use case for server side components except for data fetching because every single item on my page will always be subject to user interaction (hence: user interface).

Thanks for any clarifications :)


Solution

  • There is a great article about this in the NextJs app router documentation.

    TLDR: You are right. In a blog based system like the one you are describing, most of the use case for server components is data fetching.

    Personally, the system we have built has large dependencies and data fetching tokens that we keep on the server side of things. This significantly reduces load times for the client, and improves security. It also in some cases has allowed us to bypass writing a REST api in favor of directly querying our data.

    It doesn't seem like simple state management for toggling a sidebar would even really benefit from server side. It does not present a large dependency problem, or private tokens/etc that would preferably be kept private. As I said earlier, I agree with you on the analysis that your use case would not benefit greatly from SSR components.

    That being said, there is a lot of potential in parallel routes. This would allow you to toggle layouts, logos, or other content at the same URL using solely SSR components. If you structured your app correctly, only the 'controller/toggler' components would need to be client, and the rest could be SSR. (It is unclear if this would really provide much of a performance advantage, unless you pre-rendered all of the SSR statically and used the cache)

    I am sure you are aware of this, but you also have the option of rendering SSR components as children of CSR components, which would allow you to more dynamically choose how to structure your project.