Björn Devams

Björn

May 22, 2024

Next.js 14 Client vs Server Components.

Next.js 14 Client vs Server Components.

This blog is build using Next.js 14. To be honest, I really enjoyed it. However, one of the important things to understand when diving into Next.js is the concept of server components and client components. This blog will cover that in detail.

The Environment

Before we dive into the nitty-gritty, you need some background knowledge. Your web application can be executed in two types of environments: the server and the client.

What the Heck is a Client?

A client can be a machine or a program. Let's make this a bit more tangible. Your smartphone, tablet, or laptop are all examples of client machines. Basically, you can think of the client as your personal device that you use to browse the internet. On the other hand, a client program is the software on your device that allows the user to make requests. Examples include your web browser (e.g., Chrome, Firefox, or Safari), your weather app, or your messaging app.

The most important thing to remember is that a client can be seen as the machine or program that requests information from the World Wide Web. Now, you might be wondering how the client gets its information. For that, we must understand what a server is.

What the Heck is a Server?

A server is a computer program, not a device. This computer program has one special task: to send information to other devices or programs (aka clients) when they ask for it. A single server can serve multiple clients at the same time. Next to this, there are multiple types of servers, such as web servers, database servers, file servers, mail servers, game servers, and more. Explaining all these servers is not the point of this blog. However, it's important to remember that each type of server has a different role, but they all work together to provide you with the services and information you need. Many backend applications can be seen as servers when they provide services or resources to clients.

The Client-Server Model

Based on the text above, we can now simply explain what a client-server model is. The client-server model is an architecture on the web where:

  • Clients: Are the devices (like your phone or computer) that ask for things, such as web pages or data.
  • Servers: Are the powerful computer programs that provide what the clients ask for.

To communicate with each other, there are different protocols like HTTP, HTTPS, TCP/IP, WebSocket, Message Queues, and more. However, that's not within the scope of this blog.

Client-Side vs. Server-Side Rendering

To understand this correctly, we need to take a step back. When you are done writing your code, you need to convert your code into the code that's actually going to be used and rendered on the site. This is typically done in the build phase using 'npm run build' (or 'npm run dev' to test it locally). This command builds the files that are going to be stored on the server. When someone wants to view your website via the browser, a process called 'rendering' takes place. Rendering basically means that your code is converted into a viewable website. There are two types of rendering: Client-Side Rendering (CSR) and Server-Side Rendering (SSR).

Client-Side Rendering

In this approach, when you access a website, the client (your browser) sends a request to the server. The server then sends a minimal HTML file along with the JavaScript and any other resources needed. The client then has to run the JavaScript to render the page. Or in other words, the page is rendered on the client side. So, in this type of rendering, most of the work is done by the client.

Server-Side Rendering

Also in this approach, when you access a website, the client (your browser) sends a request to the server. However, the server responds differently. Instead of just sending the minimal HTML file along with JavaScript, the server generates the website's complete HTML plus JavaScript references before sending it back to the client. More specifically, the server runs all your code and builds out the raw HTML of your page and sends that to the client. So, in this approach, the rendering is done on the server side.

One of the advantages of this approach is that the server has higher compute power compared to someone just using a browser. As a result, we can respond much faster to the user. Additionally, since the server sends the 'full HTML' to the client, it is good for SEO. This is the reason that most of this blog uses Server-Side Rendering.

Next.js and Rendering Types

In Next.js, we can use both types of rendering. Choosing the right time and place to use one of these types of rendering is vital for building a performant application. By default, every component in a Next.js 14 app is considered a server component unless specified otherwise.

However, server components have their limitations. They can't handle user activities. For instance, you cannot use the useState() hook in a server component. If you want to handle user input on a specific page, you must mark your component as a client component by adding "use client" at the top of your file. Generally, we only want to mark components as client components when we need user interaction.

Fetching Data

The Next.js team recommends to do requests for fetching data in server components. So a common best practice use case would look like this:

export default async function ServerComponent() {
  const response = await fetch('https://dummydata.com/123');
  const data = await response.json();

  return (
    <div>
      <ClientComponent props={data.posts} />
    </div>
  );
}

Inside the server component we fetch the data. So, since we do that inside a server component this data fetching part is rendered on the server side. Moreover, we pass that data to the client component. Or in otherwords, behind the scenes, Next.js ensures that the data goes from the server to the client. When using Next.js 14, you must think carefully about which specific component you want to make a client component. As you know probably know, you definitely don't want to make every component a client component.

When you start with Next.js 14 it is important to understand this and hopefully this blog helped you a bit with that. That being said, I hope you enjoyed the article, and I'll see you in the next one.

Cheers!