NextJS Server vs. "use client" Rendering

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

NextJS Server vs. "use client" Rendering

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

NextJS Kinds of Rendering

NextJS offers various flavours for rendering your components. Before we dig deeper into them, lets establish a baseline understanding.

Server Rendering

By default nextjs components are rendered only on the server.

This is demonstrated in the below example where the log statement for 'rendering' is only seen on the server console and not in the browser.

app/page.tsx
export default function Home() {
console.log('rendering');
return (
<div>
Rendering Sample
</div>
);
}

"use client" Rendering

People often call this "client rendering", but its technically incorrect! This is because the component is actually still rendered on the server. What the use client directive really does is:

  • Enable client-side only features
  • Disables React Server Component features

The fact that a use client component is rendered both on the server and the client is demonstrated below where log statements for 'rendering' show up on the server and the browser console.

app/page.tsx
'use client';

export default function Home() {
console.log('rendering');
return (
<div>
Rendering Sample
</div>
);
}

Features only available on Server

React Server Components (components that use async/await) and server-only node modules are available only on the server.

An example is demonstrated below where the components reads its own file contents and renders them out 🤯

app/page.tsx
import fs from 'fs';

export default async function Home() {
return (
<pre>
{await fs.promises.readFile('src/app/page.tsx', 'utf-8')}
</pre>
);
}

Features only available with "use client"

Client side event handlers and most React hooks are only available in a 'use client' context.

An example is demonstrated below where the component uses useState and onClick, which are features than only work if you are under a use client directive.

app/page.tsx
"use client";

import { useState } from "react";

export default function Home() {
const [count, setCount] = useState(0);

return (
<button onClick={() => setCount((count) => count + 1)}>
Count: {count}
</button>
);
}

Guide for 'use client'

  • Start off without "use client":
    • Its the default
    • Server only rendering perform better
    • Enjoy features only available in React Server Components
  • The add "use client" when:
    • You need a client side event handler
    • You are using a React hook. Most react hooks only work in a "use client" context.
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

By default. Next year's components are rendered only on the server. Let's demonstrate that with an example. We have a simple page component and within this we will log out rendering. Whenever this component function runs, we open up the terminal and start the next year's server and then visit the page within our browser. Clearly the component has rendered perfectly fine, but a question that I want you to ask yourself at this point is that where will we find that console log? The answer might actually surprise you. This component is actually not rendered on the client at all, and this is verified by opening up the browser console

00:34

and noticing that there are no log statements. However, if you open up the next year's server that we have running in the background, we will see that log statement on the terminal. And this verifies that the component rendering in this case is only happening on the server and not on the client. Once the component is rendered on the server, the HTML is sent to the client and that is the end of the lifecycle for this particular component. With next case, we can actually opt into a hybrid model as well. HTML will be rendered on the server and then sent to the client and then the client side.

01:06

JavaScript will kick in at this point on the client React will go through a process called Hydration where it attaches the correct Java striped code to the HTML that was returned from the server. And to opt into this model, we need to add what is called a use client directive. It is a single string statement that must be at the top of your file. What it does is that it tells next year that we want to render the components from this particular file on the client as well. So if you boot up the next year server and then visit the page in the browser,

01:39

it still looks exactly the same as before. But if you open up the browser console, you can see that it is being rendered on the client. Now, the component being rendered on the client doesn't mean that it's not rendered on the server at all. As a matter of fact, if you look at the server terminal, you can see that it is still rendering on the server as well. So what is happening in this case is that the component is being rendered on the server. The HTML is returned to the client and we can verify that because that HTML is a part of the initial server response, but then the client side JavaScript will boot up

02:12

and attach any client side code that might be required. For this particular element. There are some things that are unlocked by rendering on the client and some things that are unlocked by rendering on the server. As an example, when we are rendering on the server that is the file doesn't have a use client directive, we can bring in modules that exist only on a server environment like node js. Additionally, our components can use async AWAI as an example. This particular component is going to read the source code for itself and return that to the browser. And indeed, when we look at the rendered application,

02:44

that is exactly what we find now, just like server rendering unlocks, async wait used client rendering has its advantages as well. For example, most react hooks only work if we are in a used client context. So if you want to use a simple component that has used state inside of it, we would need to be in a used client context. Additionally, if you attach a simple event handler to a dorm element, this particular event handler is going to need to execute on the browser and therefore next year's will need to ship this style script to the client and expects it

03:17

to be within a used client file. And if you open this application up within the browser, you can see it works exactly as you would expect. Let's answer a common question for next JS developers to use client or not to use client. Now we will provide you with a guide that you can use in order to determine if you need a used client on a file. However, note that if you do something wrong, for example, add, use client to this particular file which not only has asy eight components but also uses the node JS FS module, the next JS will try its best to scream at you. For example, here it is saying

03:50

that I cannot compile FS for the browser. So please remove FS before continuing. And alternatively, if you forget to provide, use client for something that does need use client, for example, this file uses state as well as event handlers. Once more, next case will scream at you. And in this particular case, it is saying that since you are trying to use use state, you should be using the use client directive. So now that we understand that help is provided, if you make silly mistakes, here is a reference guide for you so that you don't make these silly mistakes. My tip here is that you start off without use client.

04:23

First off, it is the default. It's less work for you. You don't need to add something explicitly. Now, a stronger reason for this is actually that server component perform better. They have less tower script that needs to be shipped to the client and then executed. And additionally, since they're rendered completely on the server, the server can quite easily gauge the generated HTMO and then use it again and again. Now of course for any reasonable application, you will need to add use client at some point. And the key deciding factors over here are that if you need a client side event handler, you should use client.

04:54

Or if you're using a React hook, for example, use state, then you will need to use client.