본문 바로가기

개발 공부/React

getStaticProps, getStaticPaths

getStaticProps

  • 빌드 타임(build time)에 데이터를 가져와서 페이지를 미리 생성하는 함수입니다.
  • 서버가 아니라, 배포 시점에 데이터가 수집되고 HTML로 변환됩니다.
  • 사용자 요청이 들어올 때마다 서버 요청을 보내지 않아도 되기 때문에 페이지 로딩이 빠르고 SEO에 유리합니다.

When

  • 업데이트가 거의 없거나 드문 데이터
  • SEO 최적화가 필요한 페이지 (예: 블로그, 뉴스 아카이브)

How

  • getStaticProps를 export 하여, 해당 페이지에 필요한 데이터를 빌드 시점에 미리 가져옵니다.
  • 가져온 데이터는 해당 페이지 컴포넌트의 props로 전달됩니다.
export const getStaticProps: GetStaticProps = async (context) => {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  return {
    props: {
      posts,
    },
  };
};
  • 이렇게 작성하면, 빌드 시점에 API를 호출하여 posts 데이터를 받아오고, 페이지 컴포넌트의 props로 넘겨 사용할 수 있습니다.
 

getStaticPaths

  • Dynamic Routes를 사용할 때, 어떤 경로들을 정적으로 빌드할지 정의하는 함수입니다.
  • 예를 들어 /posts/[id] 형태의 페이지가 있을 때, [id] 값들을 미리 지정할 수 있습니다.
  • fallback 옵션을 통해, 사전에 빌드되지 않은 페이지 요청도 처리할 수 있습니다.

When

  • 다양한 URL을 가진 많은 페이지를 사전에 준비할 때 (예: 상품 상세, 게시글 상세)

How

  • getStaticPaths를 export 하여, 어떤 동적 경로를 미리 생성할지 정의합니다.
  • 반환하는 paths 배열에 각 경로의 params를 지정합니다.
export const getStaticPaths: GetStaticPaths = async () => {
  const res = await fetch('https://api.example.com/posts');
  const posts = await res.json();

  const paths = posts.map((post: any) => ({
    params: { id: post.id.toString() },
  }));

  return {
    paths,
    fallback: 'blocking',
  };
};
  • 이렇게 작성하면, 각 게시글의 id에 따라 정적 페이지가 생성되며, 없는 id는 fallback을 통해 서버에서 새로 생성됩니다.
 

전체 흐름 요약

1. getStaticPaths: 어떤 path를 생성할지 결정합니다.
2. getStaticProps: 각 path에 필요한 데이터를 가져옵니다.
3. Next.js가 정적 HTML을 생성합니다.

 

 

예제: 커뮤니티 게시글 상세 페이지

상황

  • 커뮤니티 사이트를 운영하고 있습니다.
  • URL은 /community/[category]/[postId] 형태로 구성되어 있습니다.
  • 인기 많은 글은 빌드 시 미리 생성하고, 그 외 글은 사용자가 요청할 때 생성하고 싶습니다.

구성도

  • 인기글: 빌드 타임에 생성
  • 비인기글: fallback blocking을 이용해 요청 시 생성
// pages/community/[category]/[postId].tsx
import { GetStaticPaths, GetStaticProps } from 'next';
import { getPopularPosts, getPostDetail } from '@/lib/api';
import { Post } from '@/types';

interface Props {
  post: Post;
}

export default function PostDetailPage({ post }: Props) {
  return (
    <div className="p-4">
      <h1 className="text-2xl font-bold">{post.title}</h1>
      <p className="mt-2">{post.content}</p>
    </div>
  );
}

export const getStaticPaths: GetStaticPaths = async () => {
  const popularPosts = await getPopularPosts();

  const paths = popularPosts.map((post) => ({
    params: { 
      category: post.categorySlug, 
      postId: post.id.toString() 
    },
  }));

  return {
    paths,
    fallback: 'blocking',
  };
};

export const getStaticProps: GetStaticProps<Props> = async (context) => {
  const { category, postId } = context.params!;

  const post = await getPostDetail(category as string, postId as string);

  if (!post) {
    return { notFound: true };
  }

  return {
    props: {
      post,
    },
    revalidate: 60,
  };
};

 

  • Where?
    • Next.js 프로젝트의 pages/community/[category]/[postId].tsx 파일에 위치합니다.
    • 사용자가 /community/카테고리명/게시글ID 형식의 URL로 접속할 때 이 파일이 자동으로 매칭됩니다.
  • How?
    • Next.js는 사용자가 특정 URL로 접근하면, 이 파일을 인식하여 매칭된 컴포넌트를 렌더링합니다.
    • getStaticPaths가 빌드 타임에 어떤 경로를 미리 생성할지 결정하고,
    • getStaticProps가 각 경로별로 필요한 데이터를 가져와서 페이지를 생성합니다.
      • 인기 게시글은 빌드 타임에 HTML로 미리 만들어 배포합니다.
      • 비인기 게시글은 사용자가 처음 요청할 때 서버에서 실시간으로 생성(fallback: 'blocking')하여 전달합니다.
      • 이후 생성된 페이지는 정적으로 저장되어, 다음 요청부터는 빠르게 응답할 수 있습니다.

예시 흐름

  1. /community/sports/123 URL 접근
  2. Next.js가 community/[category]/[postId].tsx 파일을 찾음
  3. getStaticPaths에서 인기 게시글인지 확인
    • 인기 게시글이면: 이미 정적 HTML이 준비되어 바로 응답
    • 인기 게시글이 아니면: getStaticProps로 데이터 조회 후 HTML 생성하여 사용자에게 제공
  4. 생성된 HTML은 캐싱되어 이후 빠른 응답 가능
  • fallback: 'blocking': 빌드되지 않은 페이지는 요청이 들어왔을 때 서버에서 생성 후 사용자에게 보여줍니다.
  • revalidate 설정: 일정 시간 후에는 정적 페이지를 다시 생성할 수 있어, 데이터가 갱신됩니다.
  • notFound 처리: 잘못된 URL로 접근할 때 404 페이지를 빠르게 보여줄 수 있습니다.

 

1. getStaticPaths 호출

Next.js가 프로젝트를 빌드할 때
getStaticPaths를 자동으로 실행합니다.

2.paths 안에 있는 모든 경로를 기반으로 페이지 생성

예를 들어, paths를 이렇게 리턴했다고 가정합시다.

paths = [ { params: { category: 'sports', postId: '123' } }, { params: { category: 'music', postId: '456' } }, { params: { category: 'movie', postId: '789' } }, ];
 

 

그러면 Next.js는 이 3개에 대해 아래와 같은 정적 HTML 파일을 빌드합니다.

/community/sports/123 /community/sports/123/index.html
/community/music/456 /community/music/456/index.html
/community/movie/789 /community/movie/789/index.html

 

3. 사용자가 접근할 때

  • 사용자가 /community/sports/123에 접근하면?
    → 서버는 이미 빌드된 HTML 파일을 바로 응답합니다. (빠르고 서버 부하 없음)
  • 만약 paths에 없는 URL(예: /community/tech/999)에 접근하면?
    → fallback: 'blocking' 설정 덕분에 서버가 그때 데이터를 불러와서 HTML을 새로 만들어 보여줍니다.
 

함수 설명 용도
getStaticProps 빌드 시 데이터를 가져와 정적 페이지를 생성합니다. 데이터 불변/SEO 최적화 필요 시
getStaticPaths 어떤 동적 경로를 미리 생성할지 정의합니다. 다이나믹 라우트 준비 시