🖍️
Developer Note
  • Welcome
  • Git
    • Eslint & Prettier & Stylelint & Husky
  • Programming Language
    • JavaScript
      • Script Async vs Defer
      • Module
      • Const VS Let VS Var
      • Promise
      • Event Loop
      • Execution Context
      • Hoisting
      • Closure
      • Event Buddling and Capturing
      • Garbage Collection
      • This
      • Routing
      • Debounce and Throttle
      • Web Component
      • Iterator
      • Syntax
      • String
      • Array
      • Object
      • Proxy & Reflect
      • ProtoType
      • Class
      • Immutability
      • Typeof & Instanceof
      • Npm (Node package manager)
    • TypeScript
      • Utility Type
      • Type vs Interface
      • Any vs Unknown vs Never
      • Void and undefined
      • Strict Mode
      • Namespace
      • Enum
      • Module
      • Generic
    • Python
      • Local Development
      • Uv
      • Asyncio & Event loop
      • Context Manager
      • Iterator & Generator
      • Fast API
      • Pydantic & Data Class
    • Java
      • Compilation and Execution
      • Data Type
      • Enumeration
      • Data Structure
      • Try Catch
      • InputStream and OutputStream
      • Concurrent
      • Unicode Block
      • Build Tools
      • Servlet
      • Java 8
  • Coding Pattern
    • MVC vs MVVM
    • OOP vs Functional
    • Error Handling
    • MVC vs Flux
    • Imperative vs Declarative
    • Design Pattern
  • Web Communication
    • REST API
      • Web Hook
      • CORS issue
    • HTTPS
    • GraphQL
      • REST API vs GraphQL
      • Implementation (NodeJS + React)
    • Server-Sent Event
    • Web Socket
    • IP
    • Domain Name System (DNS)
  • Frontend
    • Progressive Web App (PWA)
    • Single Page & Multiple Page Application
    • Search Engine Optimiaztion (SEO)
    • Web bundling & Micro-frontend
      • Webpack
        • Using Webpack to build React Application
        • Using Webpack to build react library
      • Vite
      • Using rollup to build react library
      • Implementing micro frontend
    • Web Security
      • CSRF & Nonce
      • XSS
      • Click hijacking
    • Cypress
    • CSS
      • Core
        • Box Model
        • Inline vs Block
        • Flexbox & Grid
        • Pseudo Class
        • Position
      • Tailwind CSS
        • Shadcn
      • CSS In JS
        • Material UI
    • React
      • Core
        • Component Pattern
        • React Lazy & Suspense
        • React Portal
        • Error Boundary
        • Rendering Methods
        • Environment Variable
        • Conditional CSS
        • Memo
        • Forward Reference
        • High Order Component (HOC) & Custom Hook
        • TypeScript
      • State Management
        • Redux
        • Recoil
        • Zustand
      • Routing
        • React Router Dom
      • Data Fetching
        • Axios & Hook
        • React Query
        • Orval
      • Table
        • React Table
      • Form & Validation
        • React Hook Form
        • Zod
      • NextJS
        • Page Router
        • App Router
      • React Native
    • Angular
    • Svelte
      • Svelte Kit
  • Backend
    • Cache
      • Browser Cache
      • Web Browser Storage
      • Proxy
      • Redis
    • Rate limit
    • Monitoring
      • Logging
      • Distributed Tracing
    • Load Test
    • Encryption
    • Authentication
      • Password Protection
      • Cookie & Session
      • JSON Web Token
      • SSO
        • OAuth 2.0
        • OpenID Connect (OIDC)
        • SAML
    • Payment
      • Pre-built
      • Custom
    • File Handling
      • Upload & Download (Front-end)
      • Stream & Buffer
    • Microservice
      • API Gateway
      • Service Discovery
      • Load Balancer
      • Circuit Breaker
      • Message Broker
      • BulkHead & Zipkin
    • Elastic Search
    • Database
      • SQL
        • Group By vs Distinct
        • Index
        • N + 1 problem
        • Normalization
        • Foreign Key
        • Relationship
        • Union & Join
        • User Defined Type
      • NOSQL (MongoDB)
      • Transaction
      • Sharding
      • Lock (Concurrency Control)
    • NodeJS
      • NodeJS vs Java Spring
      • ExpressJS
      • NestJS
        • Swagger
        • Class Validator & Validation Pipe
        • Passport (Authentication)
      • Path Module
      • Database Connection
        • Integrating with MYSQL
        • Sequalize
        • Integrating with MongoDB
        • Prisma
        • MikroORM
        • Mongoose
      • Streaming
      • Worker Thread
      • Passport JS
      • JSON Web Token
      • Socket IO
      • Bull MQ
      • Pino (Logging)
      • Yeoman
    • Spring
      • Spring MVC
      • Spring REST
      • Spring Actuator
      • Aspect Oriented Programming (AOP)
      • Controller Advice
      • Filter
      • Interceptor
      • Concurrent
      • Spring Security
      • Spring Boot
      • Spring Cloud
        • Resilience 4j
      • Quartz vs Spring Batch
      • JPA and Hibernate
      • HATEOS
      • Swagger
      • Unit Test (Java Spring)
      • Unit Test (Spring boot)
  • DevOp
    • Docker
    • Kubernetes
      • Helm
    • Nginx
    • File System
    • Cloud
      • AWS
        • EC2 (Virtual Machine)
        • Network
        • IAM
          • Role-Service Binding
        • Database
        • Route 53
        • S3
        • Message Queue
        • Application Service
        • Serverless Framework
        • Data Analysis
        • Machine Learning
        • Monitoring
        • Security
      • Azure
        • Identity
        • Compute Resource
        • Networking
        • Storage
        • Monitoring
      • Google Cloud
        • IAM
          • Workload Identity Federation
        • Compute Engine
        • VPC Network
        • Storage
        • Kubernetes Engine
        • App Engine
        • Cloud function
        • Cloud Run
        • Infra as Code
        • Pub/Sub
    • Deployment Strategy
    • Jenkins
    • Examples
      • Deploy NextJS on GCP
      • Deploy Spring on Azure
      • Deploy React on Azure
  • Domain Knowledge
    • Web 3
      • Blockchain
      • Cryptocurrency
    • AI
      • Prompt
      • Chain & Agent
      • LangChain
      • Chunking
      • Search
      • Side Products
Powered by GitBook
On this page
  • Pre-rendering
  • Static Site Generation
  • Server Side Rendering
  • SWR

Was this helpful?

  1. Frontend
  2. React
  3. NextJS

Page Router

PreviousNextJSNextApp Router

Last updated 5 months ago

Was this helpful?

Pre-rendering

  • Traditionally, we use useEffect to fetch the data to update the ui. However, useEffect is triggered after the initial functional component is rendered

  • Therefore, we cannot see the data from the source, which is not good for search engine optimization, so that we need pre-rendering

NextJS can do pre-rendering , which have 2 types - static generation and server-rendering

Static Site Generation

GetStaticProps

  • The html file with initial data will be generated during build time, so that in every user request, the initial content of web page will be the same

// Functional Component
const Home = (props) => {
    return ...
}

// Static Generation
// The method name must be getStaticProps
// the object including props must be returned 
// and pass it to the functional component
export const getStaticProps = async () => {
  try {
    const { homeData } = await  import("../data/home.js");
    return {
      props: { homeData, error: "hi" },
    };
  } catch (error) {
    return {
      props: { error: error.message },
    };
  }
};
  • If we want to generate the page in every couple of time in order to keep the data of pre-rendering updated

export const getStaticProps: GetStaticProps = async () => {
  try {
    const { homeData } = await import("../data/home.js");
    return {
      props: { homeData, error: "hi" },
      // the page will be re-generated in every 10 seconds
      revalidate : 10
    };
  } catch (error) {
    return {
      props: { error: error.message },
      revalidate : 10
    };
  }
};

GetStaticPath

  • For the dynamic page, such as [id].js, nextjs need to knows which id should pre-render

  • If the id doesn't included, 404 default error page will be returned if setting fallback is false

// Functional Component
const Detail = () =>{
    ...
}

// Pass the path that include based on the data file
// The object including path which containg params object must be returned
export const getStaticPaths = async () => {
  try {
    const { projectList } = await import("../../data/project");
    const pathList = projectList.map(({ id }) => ({
      params: {
        projectId: id,
      },
    }));
    return {
      fallback: false,
      paths: pathList,
    };
  } catch (err) {
    return {
      fallback: true,
      paths: [],
    };
  }
};

// Get back the object from getStaticPath by context
// Then generate the corresponding data based on the param in the build time
export const getStaticProps = async (context) => {
  const { projectId } = context.params;
  try {
    const { data } = await import(`../../data/${projectId}`);
    return {
      props: { data },
    };
  } catch (err) {
    return {
      props: { error: err.message },
    };
  }
};

export default Detail;
  • fallback can also set to be blocking

import React from 'react';
import {useRouter} from "next/router";
const Test = () => {
    const route = useRouter();
    return (
        <div>
            {route.query.id}
        </div>
    )
}

export const getStaticPaths = () => {
    const pathList = ['1','2'].map(item=> ({params:{id: item}}))
    console.log(pathList);
    return  {
        fallback: "blocking",
        paths: pathList
    }
}
export const getStaticProps = (context) => {
    return {props:{}};
}
export default Test
  • Apart from 1 and 2, other id will be rendered on the server before showing the page, after rendering, the new page will be cache

  • fallback can also to be true

import React from 'react';
import {useRouter} from "next/router";
const Test = () => {
    const route = useRouter();
    if (route.isFallback) {
        return <div>Loading...</div>
      }
    return (
        <div>
            {route.query.id}
        </div>
    )
}

export const getStaticPaths = () => {
    const pathList = ['1','2'].map(item=> ({params:{id: item}}))
    return  {
        fallback: true,
        paths: pathList
    }
}
export const getStaticProps = (context) => {
    return {props:{}};
}
export default Test
  • Initially, the loading page will be shown, meanwhile, the relevant html and json will be generated on the background and then render the page. After finished, the page will be changed into full page

Server Side Rendering

  • The page will be rendered on the server for each user request, and request and response of the page can obtained through context

import React from 'react'

const servertest = () => {
    return (
        <div>
            getServerSideProps
        </div>
    )
}

export const getServerSideProps = (context) => {
    // ...
    console.log(context.req, context.res);
    if(notFound)
        return {
            notFound: true
        }
    if(!auth){
        return {
            redirect: {
              destination: '/',
              permanent: false,
            },
         }
    }
    
    return {
        props:{}
    }
      

}

export default servertest
  • Request obtained can be used to determined whether the user can be authenticated to enter the page or not

import withSession from '../lib/session'
import Layout from '../components/Layout'

export const getServerSideProps = withSession(async function ({ req, res }) {
  // Get the user's session based on the request
  const user = req.session.get('user')

  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    }
  }

  return {
    props: { user },
  }
})

const Profile = ({ user }) => {
  // Show the user. No loading state is required
  return (
    <Layout>
      <h1>Your Profile</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

SWR

  • used for client-side rendering

  • Here is the simple example with nextjs pre-rendering

  const Page = ({data:preRenderData}) => {
    const fetcher = (url: string) => axios.get(url).then((res) => res.data);
    const { data, error } = useSWR<Page>(
      `${process.env.REACT_API_URL}/sample-page`,
      fetcher,
      { initialData: preRenderData }
    );
  
    if (!data && !error) return <span>Loading...</span>;
    
    // render page...
  }
The building process