Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      SSR & SSG

      Next.js Mastery: From Fundamentals to Full-Stack

      Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.

      Server-Side Rendering (SSR)


      

      Concept

      SSR stands for "Server-side Rendering". As the name suggests, the rendering work is mainly performed on the server side.
      Let's consider a practical example: a blog post page. In many cases, it's inefficient for the client to make a request every time the page loads, especially if the client's network connection is slow. Instead, with SSR, the server takes on the responsibility of requesting the API, fetching the necessary data, and rendering it into a static HTML file. This pre-rendered HTML is then sent to the user.
      While SSR does involve making requests, the server environment typically boasts superior network conditions and device performance compared to the average client. As a result, the final rendering speed, particularly the time it takes for the first screen to load, is generally faster.
      However, it's important to note that while the overall speed is improved, the initial response time for SSR can be longer than that of Client-Side Rendering (CSR). This is because a CSR response only needs to return a minimal HTML structure, whereas an SSR response must request data from the API and render the full HTML. This difference is reflected in the performance metric known as Time To First Byte (TTFB), where SSR will typically have a longer TTFB than CSR.

      Implementation in Next.js

      Next.js supports SSR. In the Pages Router, you can implement SSR by exporting an async function named getServerSideProps. This function is called on every request, and the returned data is passed to the component as props.
      Example:
      // pages/ssr.js
      export default function Page({ data }) {
      return <p>{JSON.stringify(data)}</p>
      }
      
      export async function getServerSideProps() {
      const res = await fetch(`https://jsonplaceholder.typicode.com/todos`)
      const data = await res.json()
      return { props: { data } }
      }
      
      To use SSR, you need to export an async function named getServerSideProps. This function will be called on every request. The returned data will be passed to the component through the props property.
      
      When a request is made to this page, the server compiles the HTML file and returns it to the client. If you were to view the source of the returned HTML, you would see the data directly embedded:
      <body>
      <div id="__next">
      <p>{&quot;uerlId &quot;:1,&quot;id &quot;:1,&quot;title &quot;:&quot;delectus aut autem &quot; ,&quot;completed &quot;:false}</p>
      </div>
      ...
      

      Static Site Generation (SSG)


      

      Concept

      SSG stands for "Static Site Generation", where pages are pre-rendered into static HTML files during the build phase of an application.
      Let's return to our blog post example. If the content of a blog post is the same for all users, there's no need for the server to request data from the API every time a user visits the page. Instead, it's more efficient to fetch this data in advance, compile it into HTML files during the build process, and serve these pre-generated HTML files directly when a user visits. This approach significantly improves loading speed. When combined with CDN caching, the performance improvements can be even more substantial.

      Implementation in Next.js

      Next.js has built-in support for SSG. In fact, when a page doesn't require data fetching, SSG is used by default. Here's a simple example using the Pages Router:
      // pages/ssg1.js
      function About() {
      return <div>About</div>
      }
      
      export default About
      For pages like this that don't require data fetching, Next.js will generate a separate HTML file during the build process.
      By default, Next.js doesn't export these generated files. If you want to see the HTML files generated during the build, you need to modify the next.config.js file:
      const nextConfig = {
      output: 'export'
      }
      
      module.exports = nextConfig
      After making this change, when you run npm run build, you'll see a generated out folder in the root directory containing the HTML files created during the build process.
      

      SSG with Data Fetching


      
      There are two scenarios to consider when implementing SSG with data fetching:
      1. Page content requires data fetching: Next.js provides getStaticProps for this scenario. Here's an example:
      // pages/ssg2.js
      export default function Blog({ posts }) {
      return (
      <ul>
      {posts.map((post) => (
      <li key={post.id}>{post.title}</li>
      ))}
      </ul>
      )
      }
      
      export async function getStaticProps() {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts')
      const posts = await res.json()
      return {
      props: { posts },
      }
      }
      getStaticProps is called during the build process and passes the fetched data to the page through the props object. It's important to note the difference between getStaticProps and getServerSideProps: while they are similar in usage, getServerSideProps is called on every request, whereas getStaticProps is only called during each build.
      
      2. Page path requires data fetching: For scenarios where you need to generate multiple pages based on data (e.g., 100 articles in a database), Next.js provides getStaticPaths. This function is used in conjunction with dynamic routing. Here's an example:
      // /pages/post/[id].js
      export default function Blog({ post }) {
      return (
      <>
      <header>{post.title}</header>
      <main>{post.body}</main>
      </>
      )
      }
      
      export async function getStaticPaths() {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts')
      const posts = await res.json()
      const paths = posts.map((post) => ({
      params: { id: String(post.id) },
      }))
      // { fallback: false } means other routes should 404
      return { paths, fallback: false }
      }
      
      export async function getStaticProps({ params }) {
      // If the route is /posts/1, params.id is 1
      const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`)
      const post = await res.json()
      return { props: { post } }
      }
      In this example, both getStaticPaths and getStaticProps are called during the build process. getStaticPaths defines which paths should be pre-rendered, while getStaticProps uses the path parameters to request data and pass it to the page. When you run npm run build, you'll see multiple HTML files generated under the post folder, one for each path defined by getStaticPaths.
      
      This approach allows you to generate static pages for dynamic content, combining the performance benefits of static generation with the flexibility of data-driven pages.