DEV Community

Yu Hamada
Yu Hamada

Posted on

4

The difference of writing CSR, SSR and SSG in Next.js App Router and Page Router.

Table of Contents

  1. At the beginning
  2. What is CSR, SSR, SSG?
  3. Conclusion

At the beginning

When I first studied CSR, SSR and SSG, I struggled to understand these concepts. Recently, the introduction of App Router, which include different writing styles, has made it even more challenging. Additionally, there are still many articles that mix up these concepts.
I wrote this article to clearly the difference between them.

Client-Side Rendering(CSR)

  • Rendering HTML on the client side.
  • Receive empty HTML, CSS, JavaScript from the server side, and then create HTML using initial data.
  • The page is slow because of data acquisition and creating HTML on the client side each time.
  • Use only pages where you want to update data on the client side depending on user operation, etc.

In Next.js, there are two ways we can implement client-side rendering.

  1. Using React hooks like useEffect(), useState().
  2. Using a data fetching library SWR.

Here is an example.

'use client'

import React, { useEffect, useState } from "react";

const CsrPage = () => {
  const [products, setProducts] = useState<Product[]>([]);

  const fetchData = async () => {
    const res = await fetch("https://dummyjson.com/products");
    const data = await res.json();

    setProducts(data.products);
  };

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <>
      <h3>Built with CSR</h3>
      <br />
      <ul>
        {products.map((product) => (
          <li key={product.id}>
            {product.id}: {product.title}
          </li>
        ))}
      </ul>
    </>
  );
};

export default CsrPage;
Enter fullscreen mode Exit fullscreen mode

In page router, we don't need to use use client on the top of file  because there is no concept of client component and server component.

The process flow of CSR

Image description

Server-Side Rendering(SSR)

  • Rendering HTML on the server side, not on the client side.
  • Create HTML on the server side and return to the client after the server receives the request and retrieves the necessary data.
  • The page is fast because the server generates only the necessary pages, and the browser just displays them.
  • Use SSR only on pages where SSG can't(the website with content that changes for each user).

In SSR, we use { cache: "no-store" } in the second argument of fetch(). And don't use useEffect(), useState().

Here is an example.

import React from "react";

const SsrPage = () => {
  const res = await fetch("https://dummyjson.com/products", {
    cache: "no-store",
  });
  const data = await res.json();

  return (
    <>
      <h3>Built with SSR</h3>
      <br />
      <ul>
        {data.products.map((product) => (
          <li key={product.id}>
            {product.id}: {product.title}
          </li>
        ))}
      </ul>
    </>
  );
};

export default SsrPage;
Enter fullscreen mode Exit fullscreen mode

In page router, we need to export an async function called getServerSideProps. But In App Router, don't use getServerSideProps.

The process flow of SSR

Image description

Static Site Generation(SSG)

  • Complete the HTML construction of the entire site, including data fetching with the API, on the server side in advance of the build process.
  • Just return this file when requested.
  • The page is fast by having the page cached in the CDN.
  • SEO-friendly

In SSG, we use { cache: "force-cache" } in the second argument of fetch() (Default value { cache: 'force-cache' }, so it can be omitted). And don't use useEffect(), useState().

Here is an example.

import React from "react";

const SsgPage = () => {
  const res = await fetch("https://dummyjson.com/products", {
    cache: "force-cache",  // we can be omitted
  });
  const data = await res.json();

  return (
    <>
      <h3>Built with SSG</h3>
      <br />
      <ul>
        {data.products.map((product) => (
          <li key={product.id}>
            {product.id}: {product.title}
          </li>
        ))}
      </ul>
    </>
  );
};

export default SsgPage;
Enter fullscreen mode Exit fullscreen mode

In page router, we need to export an async function called getStaticProps. But In App Router, don't use getStaticProps.

The process flow of SSG

Image description

Conclusion

This article can be covered CSR, SSR and SSG that beginners should understand at first. In addition to them, there is also ISR to render the web page. I hope this article will serve as a first step for those new to Next.js.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (4)

Collapse
 
gnopor profile image
Blaise TAYOU

And don't use useEffect(), useState().

I am struggling to understand why we shouldn't use those hooks in SSG.
Check your note again bro. That affirmation is wrong.

Collapse
 
jamescroissant profile image
Yu Hamada • Edited

Oh, I don't think so.
useEffect() and useState() can be used in CSR. But in SSG, the page is rendered during the build time, created static HTML page and return the static files upon request. The browser is only displayed static file, not executing JavaScript like using useEffect() and useState().

Check official document too

Collapse
 
gnopor profile image
Blaise TAYOU

I use useEffect in my SSG to fetch data. When a component loads, for example, I get the query(?id=some_id) and fetch the related element. The app is an SSG app hosted on firebase hosting.

Collapse
 
long_nguyb_3502d1bc88a40 profile image
Long Nguyễb

thanks

Cloudinary image

Video API: manage, encode, and optimize for any device, channel or network condition. Deliver branded video experiences in minutes and get deep engagement insights.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay