Understand how UI rendering works in Nextjs

Next.js supports 3 type of rendering

  • Server-Side Rendering (SSR)
  • Static Site Generation (SSG)
  • Client-side Rendering.

Web developer can decide the type of rendering based on the configuration and requirements of your application.

Server-Side Rendering (SSR)

Next.js allows you to render pages on the server dynamically before sending them to the client. When a user requests a page, the server generates the HTML content for that page and sends it to the client, along with the necessary JavaScript code. The client then takes over and adds interactivity to the page.

Here’s how SSR works in Next.js:

  1. When a user requests a page, the server executes the server-side code and fetches the necessary data for the page.
  2. The server renders the React components, including the fetched data, into HTML.
  3. Server sends the HTML response to the client, which then displays the rendered page.
  4. The client-side JavaScript takes over, and the page becomes interactive.

SSR in Next.js allows search engines to crawl and index your pages since the server sends back fully-rendered HTML responses. It also ensures that the initial page load includes the necessary data, making the content available immediately.

Static Site Generation (SSG)

Next.js also supports Static Site Generation, where pages can be pre-rendered at build time. With SSG, Next.js generates HTML pages during the build process rather than at runtime for each user request. The generated pages are then cached and served as static files.

Here’s how SSG works in Next.js:

  1. During the build process, Next.js runs the server-side code and fetches the required data for each page.
  2. The server renders the React components into HTML and generates static files for each page.
  3. When a user requests a page, Next.js serves the pre-rendered HTML file, which contains the dynamic data.
  4. The client-side JavaScript takes over, making the page interactive.

SSG is ideal for content that doesn’t change frequently or doesn’t require real-time data. It offers improved performance and scalability by serving static assets directly from a CDN (Content Delivery Network).

Client-Side Rendering (CSR)

Next.js also allows you to use React’s “useEffect” and “useState” hooks to perform client-side rendering. By utilizing these hooks, you can make API calls or handle component state changes on the client-side.


  1. Create a next.js project and open it in visual studio code.
npx create-next-app rendering-example && cd rendering-example

2. Create required folders which below command

mkdir src/pages src/resources src/pages/client-rendering src/pages/server-rendering src/pages/static-rendering

3. Create blog.json in src/resource folder

    "blogs": [
            "title": "First blog",
            "description": "Sample 1"
            "title": "Second blog",
            "description": "Sample 2"

4. Create index.js in src/pages/static-rendering folder and check http://localhost:3000/static-rendering

import React from 'react'
import { promises as fs } from 'fs';
import path from 'path';

const Page = (props) => {
    return (
        <div>{props.blogs.map(x=>(<li key={x.title}>{x.title}</li>))}</div>

export async function getStaticProps({ param }) {
    const jsonDirectory = path.join(process.cwd(), 'src/resource');
    const data = await fs.readFile(jsonDirectory + '/blog.json', 'utf8');
    //const data = fs.readFile('../../resource/blog.json')
    console.log('data:', data)
    return {props: JSON.parse(data)}

export default Page;

5. Create index.js in src/pages/server-rendering folder and check http://localhost:3000/server-rendering

import React from 'react'

const Page = (props) => {
    return (
        <div>{props.posts.map(x=> (<li key={x.id}>{x.title}</li>))}</div>

export async function getServerSideProps({ param }) {
   const post = await fetch('https://my-json-server.typicode.com/typicode/demo/posts')
    return {props: {posts: await post.json()}}

export default Page;

6. Create index.js in src/pages/client-rendering folder and check http://localhost:3000/client-rendering

import React, { useEffect, useState } from 'react'

export default function index() {
    const [posts, setposts] = useState([]);
    const [showPosts, setshowPosts] = useState(false);
    useEffect(() => {
    }, [posts]);
    const fetchData = async () => {
        const post = await fetch('https://my-json-server.typicode.com/typicode/demo/posts')
        if(post.status!= 200) {
        } else {
            const data = await post.json()
  return (
        <button className='btn bg-blue' onClick={fetchData}>Render on client side</button>
        {showPosts && posts.map(post => (<li key={post.id}>{post.title}</li>))}

Leave a comment