chorock.page
소개글시리즈프로젝트
© 2026 chorock.page
← 목록으로
Next.js 기초 - Page Router · 9/11
← 이전 글다음 글 →
Next.jsweb

Page Router (8) - 정적 사이트 생성 (SSG)

2026.09.16 · 4분 읽기 · 조회 0

목차
SSR (복습)정적 사이트 생성 SSG장점단점구현 방법context 차이점동적 경로Fallback 옵션falseblockingtrue

SSR (복습)

  • 가장 기본적인 렌더링 방식
  • 요청이 들어올 때 마다 사전 렌더링을 진행 함
  • 요청이 들어올 때 마다 서버에 새로운 데이터 요청
    -> 항상 페이지의 데이터가 최신
    -> 데이터의 응답 속도가 느릴 시 로딩 속도가 느릴 수 있음

정적 사이트 생성 SSG

  • SSR의 단점을 해결하는 사전 렌더링 방식
  • 빌드 타임에 페이지를 미리 사전렌더링 해 둠
    -> 데이터 응답 속도가 느려도 빌드 타임에 일어나 상관없음

장점

사전 렌더링에 많은 시간이 소요되는 페이지더라도 사용자의 요청에는 매우 빠른속도로 응답 가능

단점

빌드 타임 이후에는 다시는 페이지를 새롭게 생성하지 않음 -> 최신 데이터 반영은 어렵다

구현 방법

간단하다.

export const getServerSideProps = () => {
  const data = "hello";
 
  return {
    props: {
      data,
    },
  };
};

이것은 SSR을 구현하는 함수였다.

export const getStaticProps = () => {
  const data = "hello";
 
  return {
    props: {
      data,
    },
  };
};

getServerSideProps -> getStaticProps 로 바꿔주면 해당 컴포넌트는 SSG 방식이 된다. return 형식도 같다.

// index.tsx
export default function Home({data} : any){
  console.log(data)
  return <div>...</div>
}

그리고 프롭스로 내려오는 데이터의 타입도 역시

InferGetStaticPropsType<typeof getStaticProps>

이렇게 정의해주면 된다.

context 차이점

export const getStaticProps = (
  context : GetStaticPropsContext) => {
  
  const query = context.query //  불가능
 
  return {
    props: {
    },
  };
};

SSR과 마찬가지로 해당 함수도 context를 인자로 사용할 수 있다.
그러나 쿼리스트링으로 넘어오는 query 값은 존재하지 않는다.
애초에 빌드 타이밍에 렌더링이 되는데, 빌드 타임에 쿼리 스트링은 존재하지 않으니 그것에 유의한다.

동적 경로

동적 경로의 경우를 보자.
/book/1, /book/2 등 동적경로를 갖는 페이지를 다음과 같이 만들었다.

// book/[id].tsx
export const getStaticProps = (
  context : GetStaticPropsContext) => {
  
  const id = context.params.id; // 동적경로를 가져와서
  const books = fetch(id) // get 요청
 
  return {
    props: {
      books    // 파라미터로 넘겨주기
    },
  };
};

다음과 같이 구현하면 컴포넌트 측에서 불러온 books 데이터를 사용할 수 있을 것이다.
그러나 이렇게만 끝내면 오류가 발생한다.

getStaticPahts 가 필요하다고 한다. 원인은 확실하다.

동적 경로는 이렇게 많은 페이지들을 만들 수 있다. [id] 값에 따라 달라진다.


이러한 많은 페이지들을 빌드 타임에 사전 렌더링하려면, 먼저 어떤 경로들이 존재할 수 있는 지 먼저 설정해주어야 한다.
[id]가 얼마나 있을지 모른다고 무한 개의 페이지를 만들 수는 없다.

경로를 미리 설정해주는 함수가 getStaticPaths 이다.

export const getStaticPaths = () => {
  return {
    paths: [
      { params: { id: "1" } },
      { params: { id: "2" } },
      { params: { id: "3" } },
    ],
  };
};

다음과 같이 정의하면 되며 반환값은 {paths : [{객체1}, {객체2}, {객체3}]} 형식이며,
객체는 {params : { id : "숫자"}} 형식으로 적으면 된다.
내부의 숫자는 무조건 string으로 명시해주어야 한다. 이렇게 하면 3개의 동적 경로가 설정된다.

Fallback 옵션

export const getStaticPaths = () => {
  return {
    paths: [
      { params: { id: "1" } },
      { params: { id: "2" } },
      { params: { id: "3" } },
    ],
    fallback: false,
  };
};

두 번째 값으로는 fallback이 들어가는데, 이는 명시한 id 범위 밖의 동적경로로 진입했을 때 실행할 기능을 정의할 수 있다.

false

404 not found를 반환한다.

blocking

해당하는 페이지를 즉시 생성한다.
첫 요청 시에는 서버가 렌더링을 하고, 두 번째 부터는 이미 생성된 페이지를 보여준다.
새로운 데이터가 계속 추가되어야 하는 경우에 쓰면 되겠다.
그러나 첫 요청 및 렌더링 시에 서버의 응답이 느리면 그만큼 로딩 속도가 느려진다는 단점이 있다.

true

똑같이 사전렌더링에 없던 페이지 요청 시 렌더링을 해준다.
하지만 먼저 Props 가 없는 페이지를 반환해준다.

export const getStaticProps = async (context: GetStaticPropsContext) => {
  const id = context.params!.id;
  const book = await fetchOneBook(Number(id));
  return {
    props: { book },
  };
};

props 는 해당 해당 함수의 리턴값에서 컴포넌트로 내려주는 값으로 서버에서 받아오는 데이터라고 생각하면 된다.
데이터가 없는 페이지를 먼저 반환해준다.
그리고 따로 Props를 계산하고 나중에 내려준다.

blocking 처럼 요청 시에 사전렌더링을 해서 내려주면서도, 빈 페이지를 먼저 내려줄 수 있기 때문에 로딩 체감 시간을 단축시킬 수 있다는 장점이 있다.

폴백 상태(빈페이지 + 데이터 불러오는 중)를 감지해서 로딩 중 메세지를 띄워주면 좋다.

export default function Page(생략){
  const router = useRouter();
  if (router.isFallback) return "로딩 중"
 
  if (!book) return "오류 발생"
}

다음과 같이 router.isFallback을 이용하면 폴백 상태를 감지할 수 있다.

초록
초록

앱과 웹을 만들고, 직접 운영하며 기록합니다.

댓글

giscus로 동작하며 GitHub Discussions에 저장됩니다.

관련 글

Next.js 기초 - App RouterNext.jsweb

App Router (11) - 서버 액션 (Server Action)

2026.09.29·2분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (10) - 우아하게 에러 핸들링하기 (error.tsx)

2026.09.28·3분 읽기·조회 0
Next.js 기초 - App RouterNext.jsweb

App Router (9) - 스트리밍

2026.09.28·3분 읽기·조회 0

목차

SSR (복습)정적 사이트 생성 SSG장점단점구현 방법context 차이점동적 경로Fallback 옵션falseblockingtrue