Unravelling Next.js Server Components: A Comprehensive Guide

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Next.js Complex State Management Patterns with RSC course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Next.js Complex State Management Patterns with RSC, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Next.js Complex State Management Patterns with RSC
  • [00:00 - 00:16] Alright, welcome to module 4. Up until now, everything that we covered might have sounded familiar if you were coming from React or previous version of Next . However, we're starting to go into more unknown territory for some of you.

    [00:17 - 00:32] And this is why this course was created essentially to understand how server components work and how they interact with state. But let's not get ahead of ourselves. Let's first cover what server components are and when you should use them versus a client component.

    [00:33 - 00:46] So let's get started. So as I mentioned in previous videos, server components are a new addition to the React environment. And Next, since version 13 made them the default type of components whenever you're creating a new one.

    [00:47 - 01:10] If you're not opting into the client component with the use client directive as we saw before, then your component is going to default into a server component. Unlike the standard server side rendering or even the static generation rendering technique, server components enable you to write UI logic that only gets executed on the server with some limitations, which we'll get to in a sec.

    [01:11 - 01:29] This rendering mode is ideal for sections of your application that are not really interactive, essentially, code that will not really provide any feedback to the user that should be rendered on the server. So the key benefits of server components over client components is that server components do not ship any JavaScript to the clients.

    [01:30 - 01:45] Remember, when you're writing your component, there is a piece of JavaScript that essentially describes the logic of your component. And then there is a final return statement where you define the markup of your component.

    [01:46 - 02:01] When you're creating a client component, both parts are needed on the client side to make sure that your client component is interactive and is doing everything that it needs to do in it's keeping the state. The state probably is reacting to events and so on.

    [02:02 - 02:21] On the server side, however, all the previous JavaScript code before the return statement, it's executed directly on the server. And the only thing that gets said to the client is the final bit, the markup that gets rendered on the server and then that output gets sent back to the client.

    [02:22 - 02:31] In practice, that means that you're reducing the bundle size of everything that gets shipped to the client. This is one of the main reasons why server components were created.

    [02:32 - 02:46] So significantly reduce the amount of code that gets sent to the client whenever there is no need for that code. Because if you think about it, whenever you create a client component, your code, everything that you write, the logic and everything gets shipped to the client.

    [02:47 - 03:10] But there is also a lot of code around your own code that needs to be shipped and executed on the client to wire it up essentially to rehydrate your component into the actual version that you want to be running. Because remember that client components, there is a first static version rendered and then when it gets hydrated, everything gets put into place.

    [03:11 - 03:23] To make those connections and to make everything warped, there is a load code that has to be shipped to the client and has to work on the client. That is resource intensive on the client device and also adds a lot of data to be transferred.

    [03:24 - 03:31] So the bundle size increases significantly. Imagine having all that extra code for no risk.

    [03:32 - 03:43] If your static markup doesn't really require any hydration, then why would you add all that extra bundle size? There is no reason for it. So that's what server components are great for.

    [03:44 - 03:59] They simply generate everything on the server and they ship what the user should see, nothing else. Now, I know that it sounds a lot like static generation and it sounds a lot like server-side rendering, but it's actually a distant custom of them.

    [04:00 - 04:21] Because these techniques are used to render entire pages when in the case of server components, these are specific components that get rendered and then shipped. In fact, these components are streamed to be more precise, imparinated potentially, to the client application through React code.

    [04:22 - 04:46] Not only that, but this is a very cool feature. Server components can be cached , so you can potentially just render your component once and then use it throughout your application without having to even go back to your server and re-execute the code. So that's a very cool feature and it saves a lot of round trips and a lot of data from being transferred, honestly.

    [04:47 - 05:02] Granted, they are great. Server components are also somewhat limited on what they can do, especially when compared to their older brother, the client components. While server components offer a brand new realm of possibilities, they come with specific constraints.

    [05:03 - 05:20] To be more precise, they can't execute any React code that is related to state management or side effects. The use effect code is not available, anything related to state or context is also not available because for that code to run, you need a browser and you need React.

    [05:21 - 05:48] On the backend, you don't really have all those features. Remember that on the server, we're just pre-rendering these components and then shipping it to the client. That shipping process is actually, if we want to get into more details, they are formatted in what they call React Server Components payload, which is a binary format that reacts, understood on the client, and is capable of performing optimizations on it, essentially.

    [05:49 - 06:05] But it doesn't really include any interactive code to be added into that payload, so it's just the HTML of your component. Something else that your server components are not going to have access to, and we've covered this before, are the DOM API and the browser APIs.

    [06:06 - 06:17] This is simply because on the server, there is no browser. We're not using a headless browser to render this or anything. These APIs are simply not accessible to our components.

    [06:18 - 06:41] If you think of the examples from the previous module, like the Shield Ocator element that was using the Shield Ocation API from the browser, that could not be a server component. It would simply not work. And this is fine, actually. I talk about the lack of these features as limitations for server components, but in reality, this is just how they work.

    [06:42 - 07:01] They are not meant to have access to any of these, because on the server, you want to render the static markup of your components, and essentially what makes the static section of your UI. And because this is the static side of it, there is no interactivity, there is no state, there is no reactivity to think about it.

    [07:02 - 07:21] So if there is none of it, then why would we want to have access to events, to event handlers, to, or to any of these APIs that we don't really need. So again, it might feel like we're missing things, but in reality, server components should not be compared one to one to client components.

    [07:22 - 07:34] They're just a different type of components, and they have a completely different set of use cases that they should be considered for. All in all, server components might seem like they're a bit limited, but they 're actually quite powerful, as I was saying.

    [07:35 - 07:54] Look at the following example, for instance. This is the code for our navigation bar, which actually, let me just show it to you how it works before we look at the code. So if you think about this is our task manager application, the one I've been showcasing so far, the navigation bar is this up top here.

    [07:55 - 08:07] So it has a task manager, this is the name of our app, and then it has a user menu on the right corner, which shows my username. And if I click on it, it will give me the option to look out.

    [08:08 - 08:21] So 99% of this code is static. I don't really have to do anything other than being able to click on this and dynamically show the name of my user.

    [08:22 - 08:31] So let's go back now to the code to see how that works. So you can see, the first thing you can see is that there is no use client here , so we're talking about the server component.

    [08:32 - 08:42] Why is this a server component? Because again, 99% of the markup for this navigation bar is static. The name of my application is static, that's not going to change.

    [08:43 - 08:55] And the data that I need to have the dynamic section of it, I need to get it from the database. So I take advantage of the fact that the server component is running on the backend.

    [08:56 - 09:08] And I will grab my logged in cookie, which has my user ID. And we're going to get into more details about how this and why this is working like this in future videos.

    [09:09 - 09:17] But right now, just accept this as a truth, essentially. The cookie that I'm using contains my user ID or the database.

    [09:18 - 09:34] And this is a sign that I've been logged in into a system. So this server component is going to read the cookie and using that ID is going to get my user information from the database through the asynchronous function called get user by ID.

    [09:35 - 09:51] And then the component is going to use the user data as a prop for the user menu component. The user menu component is actually going to require interactivity, which makes it a client component.

    [09:52 - 10:04] So here I'm mixing a server component for the static section of my UI. And this small bit of the navigation bar that has to be interactive becomes a client component.

    [10:05 - 10:17] So this is the power that I've been talking about. 99% of my top section of the application in this case is going to be statically rendered and cached by next.

    [10:18 - 10:47] So whenever I refresh the page, I'm just getting exactly the same result because honestly, I don't have a need to constantly go back to the database to gather my user data if I already have it. And the bit that is not going to be static, it's just going to be a placeholder whenever this payload is created for the server component and react will now to rehydrate that particular client section in the browser.

    [10:48 - 11:16] And do everything it needs to do for the client component as it would normally, but the rest of it, the extra code around it, is going to be statically generated and rendered on the server side. So in practice, and I hope that this example makes that clear, you'll use server components to tap into server resources and seemingly blend them into your app's UI, improving performance while maintaining and scalable.

    [11:17 - 11:32] And secure application. So we'll look into more details about when using server components is such a great idea in future videos. But for now, remember that server components provide a powerful tool for rendering non interactive content on the server.

    [11:33 - 11:42] So that is key, it has to be non interactive. And it really provides security and improve the performance of your application overall.

    [11:43 - 12:12] Really, and in the end, it reduces the payload that has to be transferred to the client, and it also reduces the amount of processing that the client has to do, because it will only has to focus on hydrating client components and all the entire application. As server components continue to evolve, they will definitely help reshape the way we think about base architecture, and the way we decide how and when to render our components.

    [12:13 - 12:16] So until the next video, keep coding and I'll see you on the next one.