본문 바로가기
카테고리 없음

Data Fetching > getStaticPaths [공식 문서로 공부하는 Next.js]

by 룰루리랄라리 2022. 1. 11.

getStaticPaths

Basic Features > Data Fetching > getStaticPaths

 

 

언제 getStaticPaths를 사용하나요?

페이지에 동적 경로를 사용하고 정적으로 pre-rendering하는 경우

동적 경로를 사용하는 페이지에서 getStaticPaths라는 비동기 함수를 내보내는 경우 모든 경로를 정적으로 사전 렌더링합니다.

export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } } // See the "paths" section below
    ],
    fallback: true, false, or 'blocking' // See the "fallback" section below
  };
}

 

paths key (필수)

paths key는 사전 렌더링 될 경로를 결정합니다.
예시) pages/posts/[id].js라는 동적 경로를 사용하는 페이지에서 getStaticPaths를 export 하고 paths를 반환하는 경우

return {
  paths: [
    { params: { id: '1' } },
    { params: { id: '2' } }
  ],
  fallback: ...
}

위의 코드의 경우 pages/posts/[id].js의 페이지 컴포넌트를 사용하여, posts/1, posts/2는 빌드할 때 정적으로 생성합니다.
각 매개변수의 값은 페이지 이름에 사용된 매개변수와 일치해야 합니다.

 

  • 만약 페이지 이름이 pages/posts/[postId]/[commentId]로 구성된 경우 params에는 postIdcommentId가 포함되어야 합니다.

  • 페이지 이름이 모두 catch-all 경로를 사용하는 경우(pages/[...slug]) params에는 배열인 slug가 포함됩니다.
    pages/foo/bar인 경로이면 slug는 ['foo','bar'] 배열이 되고, Next.js는 /foo/bar를 정적인 페이지로 생성합니다.

  • 만약 페이지가 선택적인 catch-all 경로를 사용하는 경우, null,[],undefined, false 를 제공하여 최상위 경로를 렌더링합니다.
    예를 들어 pages/[[...slug]]이고 slug가 false라면 정적으로 '/'를 생성합니다.

 

fallback key (필수)

fallback key에는 boolean 값입니다.

fallback:false

fallback 이 false인 경우 getStaticPaths에서 return 하지 않은 모든 경로는 404 페이지가 됩니다.
pre-render 할 경로가 적은 경우 fallback:false이면 빌드 시간 동안 모든 페이지들이 정적으로 생성됩니다.
새 페이지가 자주 추가되지 않는 경우에 유용합니다.

하지만 데이터가 추가되고 새 페이지를 rendering 해야하는 경우 빌드를 다시 실행해야합니다.

 

아래 코드는 pages/posts/[id].js라는 페이지당 하나의 블로그 게시물을 pre-rendering 하는 예입니다.
게시물의 목록getStaticPaths에 의해 CMS에서 가져와 return 됩니다.

그런 다음 각 경로의 페이지에 대해 getStaticProps를 사용하여 CMS에서 데이터를 가져옵니다.

// pages/posts/[id].js

function Post({ post }) {
  // Render post...
}

// getStaticPaths은 빌드 시 호출
export async function getStaticPaths() {
  // 외부 api 호출
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  // 'posts'리스트에서 pre-render할 경로 가져오기
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))

  // 빌드시 paths만 pre-render 합니다.
  // { fallback: false }는 pre-render되지 않은 그 외의 경로는 404 임을 의미합니다.
  return { paths, fallback: false }
}

// getStaticProps 또한 빌드 시 호출
export async function getStaticProps({ params }) {
  // params에는 post의 id가 포함되어있습니다.
  // 경로가 /posts/1과 같으면 params.id는 1입니다.
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  // props를 통해 페이지에 게시물 데이터 전달 
  return { props: { post } }
}

export default Post

fallback:true

fallback이 true이면 getStaticProps의 동작이 바뀝니다.
getStaticPaths에서 return 경로는 getStaticProps에 의해 빌드 시 HTML로 렌더링됩니다.
빌드시 생성되지 않은 경로는 404페이지(fallback:false)를 생성하지 않는 대신 대체 페이지를 제공합니다.

사용자 관점에서 페이지는 대체 페이지(로딩 페이지)에서 전체 페이지(데이터가 나오는 페이지)로 교체됩니다. 이와 동시에 이 경로를 미리 렌더링된 페이지 목록에 추가하여 추후에 동일한 경로 요청이 올 경우 미리 렌더링된 페이지가 제공됩니다.

Fallback pages

  • props가 비어있습니다.
  • 라우터가 fallback이 렌더링되고 있는지 감지할 수 있습니다. router.isFallback=true가 됩니다.
// pages/posts/[id].js
import { useRouter } from 'next/router'

function Post({ post }) {
  const router = useRouter()

  // 만약 페이지가 아직 만들어지지 않았다면 router.isFallback이 ture가 되어 이 부분이 보여지게 됩니다.
  // 처음에는 getStaticProps() 실행이 완료될 때까지
  if (router.isFallback) {
    return <div>Loading...</div>
  }

  // Render post...
}

// This function gets called at build time
export async function getStaticPaths() {
  return {
    // 오직 `/posts/1` 과 `/posts/2`만 빌드시 생성됩니다.
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
    // 정적으로 추가 페이지 생성할 수 있습니다. 예시: `/posts/3`
    fallback: true,
  }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return {
    props: { post },
    // 요청이 들어오면, 초당 한 번씩 재 생성합니다.
    revalidate: 1,
  }
}

export default Post

When is fallback: true useful?

데이터에 의존하는 정적 페이지가 매우 많은 경우에 유용합니다.(모든 제품을 pre-render하고 싶지만 빌드시간이 오래걸리는 매우 큰 전자 상거래 사이트)

대신, 작은 하위 집합을 정적 생성하고 나머지 페이지에 fallback:true를 사용할 수 있습니다. 아직 생성되지 않은 페이지를 요청하면 사용자는 로딩 표시가 되어있는 fallback 페이지를 보게 됩니다.

 

getStaticProps가 완료되면 페이지가 요청된 데이터로 렌더링 됩니다. 이후 동일한 페이지를 요청하는 모든 사람은 정적으로 미리 렌더링된 페이지를 받게 됩니다.

이를 통해 사용자는 빠른 빌드와 정적 생성의 장점을 유지할 수 있습니다.

fallback:true 는 페이지를 업데이트 하지 않습니다.

fallback:blocking

getStaticPaths에서 반환되지 않은 새로운 경로는 SSR과 동일하게 HTML이 생성될 때까지 기다렸다가 향후 요청을 위해 캐시되어 경로당 한 번만 발생합니다.
getStaticPaths에서 반환된 경로는 getStaticProps에 의해 빌드 시 HTML로 렌더링됩니다.
빌드 시 생성되지 않은 경로는 404 페이지를 생성하지 않습니다. 대신 Next.js는 첫 번째 요청에서 SSR을 수행하고 생성된 HTML을 반환합니다.


완료되면 브라우저는 생성된 경로에 대한 HTML을 수신합니다. 사용자의 관점에서 "브라우저가 페이지를 요청하는 중"에서 "전체 페이지가 로드됨"으로 전환됩니다. 로딩/폴백 상태의 플래시가 없습니다.
동시에 Next.js는 이 경로를 미리 렌더링된 페이지 목록에 추가합니다. 동일한 경로에 대한 후속 요청은 빌드 시 미리 렌더링된 다른 페이지와 마찬가지로 생성된 페이지를 제공합니다.


Technical details

  • getStaticProps와 함께 사용
    동적 경로 매개변수가 있는 페이지에서 getStaticProps를 사용하는 경우 getStaticPaths를 사용해야 합니다.
    getServerSideProps와 함께 getStaticPaths를 사용할 수 없습니다.

  • 서버 측에서 빌드 시에만 실행
    getStaticPaths는 서버 측에서 빌드 시에만 실행됩니다.

  • 페이지에서만 허용됨
    getStaticPaths는 페이지에서만 내보낼 수 있습니다. 페이지가 아닌 파일에서는 내보낼 수 없습니다.
    또한 내보내기 비동기 함수 getStaticPaths() {}를 사용해야 합니다. 페이지 구성 요소의 속성으로 getStaticPaths를 추가하면 작동하지 않습니다.

  • 개발 중인 모든 요청에 대해 실행
    개발(다음 개발)에서는 모든 요청에 대해 getStaticPaths가 호출됩니다.

 

 

Basic Features: Data Fetching | Next.js

Next.js has 2 pre-rendering modes: Static Generation and Server-side rendering. Learn how they work here.

nextjs.org

 

댓글