DevelopmentDesignUI/UXGraphics
About Me
About Me

Understanding Client-Side Rendering (CSR) in Next.js

blog thumbnail
next
04 November 2024
Client-Side Rendering (CSR) is a common approach in modern web applications, where the rendering of the content is done in the browser rather than on the server. Next.js, a popular framework for React, supports CSR, enabling developers to build interactive and dynamic user experiences. In this blog post, we'll explore what CSR is, its benefits, and how to implement it in a simple Next.js application by fetching user data from an API.

What is Client-Side Rendering?

In CSR, the browser downloads a minimal HTML page, and then JavaScript is executed to render the content dynamically. This means that when users navigate to a page, the server sends only the initial HTML, and subsequent data fetching and rendering are done on the client side.

Benefits of CSR

Interactivity: CSR allows for rich user interactions and dynamic updates without the need for full page reloads. Reduced Server Load: By offloading rendering to the client, the server can handle more requests since it doesn't need to generate HTML for every request. Faster Subsequent Loads: After the initial load, navigating to different parts of the application can be quicker as the browser can fetch data and render views without going back to the server for a new HTML page.

Implementing CSR in Next.js

Let’s create a new page that fetches user data using Client-Side Rendering. Create a new file named users.tsx in the pages directory and add the following code:
Code
1// pages/users.tsx 2 3import React, { useEffect, useState } from 'react'; 4 5// Type definition for User 6interface User { 7 id: number; 8 name: string; 9 email: string; 10} 11 12// UsersPage component 13export default function UsersPage() { 14 const [users, setUsers] = useState<User[]>([]); 15 const [loading, setLoading] = useState<boolean>(true); 16 17 // Function to fetch users from an API 18 const fetchUsers = async () => { 19 const response = await fetch('https://jsonplaceholder.typicode.com/users'); 20 const data = await response.json(); 21 setUsers(data); 22 setLoading(false); 23 }; 24 25 // Fetch users when the component mounts 26 useEffect(() => { 27 fetchUsers(); 28 }, []); 29 30 // Render loading state or user list 31 return ( 32 <div> 33 <h1>User List</h1> 34 {loading ? ( 35 <p>Loading...</p> 36 ) : ( 37 <ul> 38 {users.map(user => ( 39 <li key={user.id}> 40 <strong>{user.name}</strong> - {user.email} 41 </li> 42 ))} 43 </ul> 44 )} 45 </div> 46 ); 47}

Code Breakdown

Imports: We import React and hooks (useEffect, useState) to manage the component state and lifecycle. User Interface: We define a TypeScript interface User to specify the structure of user objects, including id, name, and email. Component State: The UsersPage component uses the useState hook to manage two pieces of state: users: An array to hold the user data. loading: A boolean to track whether the data is still being fetched. Data Fetching Function: The fetchUsers function uses the Fetch API to retrieve user data from a public API (jsonplaceholder.typicode.com). After fetching the data, it updates the users state and sets loading to false. useEffect Hook: The useEffect hook calls fetchUsers when the component mounts. This ensures that the user data is fetched only once when the component is first rendered. Rendering the Component: The component conditionally renders either a loading message or the list of users based on the loading state.

How It Works

When a user navigates to /users, the initial HTML is sent from the server. Once the page is loaded in the browser, the fetchUsers function is called to fetch the user data. While the data is being fetched, a loading message is displayed. Once the data is retrieved, the user list is rendered on the page without requiring a full reload.