DEV Community

Cover image for Next 13 - Server and Client components
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Next 13 - Server and Client components

With Next 13 the team made quite big changes regarding how components render.
Not that it's all-new, but they seem to have simplified it and changed the defaults.

So let's take a closer look at how rendering works in Next 13.

What is Server vs. Client?

We'll first have to address what is seen as the server and the client.

  • Server: A actual server that hosts your code can receive a request, do some calculations and send back a response once those are complete.
  • Client: The browser a user's device sends a request to the server and does some calculations in the browser to render the correct layout.

As you can see, the tipping point lies in where the calculations happen.

So what exactly did the ecosystem look like before Next 13?

In general, with React, everything happens on the client side. Next solve this by breaking your React components down into pages that could partially be rendered on the server.
However, this generated HTML on the server, which had to be hydrated on the client again, meaning we needed extra JavaScript.

With the introduction of the clear distinguishment between server and client-side components, React can render on the server OR the client.

The new default in all this is server-side rendering.

Server side: Static or Dynamic rendering

With this addition of being Server side first, we get another two choices.
Either we render statically or dynamically.

Let's take a closer look at what that means.

  • Static: Both server and client components can be prerendered on the server at build time. This will cache the result and reuse that cache on the following requests. (Equivalent of SSG and ISR in pre-13 terms)
  • Dynamic: Server and client components are rendered on request and will not be cached. (Equivalent of SSR pre-13 terms)

How to create client components?

You might wonder, if these server components are the new default, how do I use client components?

And Next makes this super simple by adding a directive at the top of your file.

'use client';

export default function YourPage() {
  //Client-side code
}
Enter fullscreen mode Exit fullscreen mode

Yep, that directive will take care of everything!

When to use which one?

It might feel tricky to know which one to use at which stage, so let's look at Next's directive on this.

Let's break it down by what you might need.

  • Fetching data? -> Server component
  • Access backend resources -> Server component
  • Keep sensitive information on the server -> Server component
  • Reduce JavaScript code -> Server component

  • Add interactivity (click/change listeners) -> Client component

  • Use state or lifecycle effects -> Client component

  • Browser-only APIs -> Client component

  • Custom hooks that need any of the above -> Client components

You might think, ok but surely they need to mix and match, and indeed they do.

The advice given by Next is that we opt to make component server-side where possible and extract the ones that need client-side rendering.

This way, our server components only need to render that specific small component on the client.
But more on this later on when we try them out.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Latest comments (3)

Collapse
 
peerreynders profile image
peerreynders • Edited

This way, our server components only need to render that specific small component on the client.

Please correct me if I'm wrong.

tldnr:

  1. The “only” advantage Next.js 13 derives from React Server Components (RSC) is that it doesn't ship the Server Component code to the client (besides any other advantages that may derive from execution on the server).
  2. Next.js 13 doesn't actually leverage the full vision of RSCs as presented in the December 2020 Data Fetching with React Server Components demo. I was left with the impression that RSCs (with the appropriate framework support) could re-render on the server and push an update to the client even after the initial server render; something that Next.js 13 doesn't support at this time.

As I understand it in Next.js 13 for the initial render

Client Components ship:

  1. HTML from the client component SSR render
  2. Hydration data to “replay” the component to the state it was at on the server
  3. The JavaScript code necessary to rerender the component on the client.

Server Components ship:

  1. HTML from the server component SSR render
  2. The React Nodes that the server component generated to be dropped into the vDOM on the client side.

So:

  • The difference is the lack of client side component code for Server Components as their React Nodes just need to sit in the vDOM.
  • However past the point of the initial render Next.js 13 doesn't really support the application (session) at all, so a bunch of other dependencies will still be needed to support deep session client side applications (perhaps making the server component savings insignificant).

As I understand what the 2020 RSC demo was trying to achieve:

  1. There was no HTML from SSR. Ultimately this isn't relevant because that's a detail that is up to the implementing (meta) framework to decide.
  2. Client Component code is still shipped to the browser to support client-side rendering.
  3. Server Components render React Nodes on the Server and those React Nodes are shipped to the browser and dropped directly into the vDOM for client side rendering.

So the idea was to only have light-weight client components in the browser that are able to trigger actions on the server where server components do the data fetching and produce the necessary React Nodes to send back to the browser during the entire deep application session.

To achieve this with Next.js 13 today you would still have to add something like tRPC—undermining the benefit of RSCs which should make that entirely unnecessary.


I think ultimately it's because of this lack of progress in the past two years why Hydrogen is swapping to the Remix approach.

They primarily want:

  • Data fetching on the server over deep sessions
  • Declarative UI on both server and client

The no-JS scenario actions trigger full page reloads, while in SPA mode just the page data is re-fetched.

PS: Also with the Remix approach using Preact may become feasible in the near future without Preact having to implement Server Components (yielding a smaller initial bundle).

Collapse
 
dailydevtips1 profile image
Chris Bongers

I'm not quite up to date with the original RSC proposal, but yes you are right as far as implementation seems to go now.

A lot of documentation is still in the making so it might also change once fully implemented, but as of now. it would seem they will also need to inject some kind of "re-fetching" mechanism.

Have you seen any other frameworks moving towards this heavy server side approach that do follow the intended proposal? (Just curious to see other implementations to this one)

Collapse
 
peerreynders profile image
peerreynders • Edited

In terms of React I was only aware of Hydrogen and they have pivoted now to Remix.

However the general approach is experimentally being used by SolidStart in solid-movies.app (beta). Islands can contain server rendered components which can be re-fetched (the returned HTML partial is then diffed into the existing DOM).

It's detailed in Client-side Routing without the JavaScript.