본문 바로가기

Next.js

Next.js 4-1. getSaticPaths

  페이지에 동적 경로가 있고 getStaticProps를 사용하는 경우 정적으로 생성할 경로 목록을 정의해야 한다. export 하는 함수가 동적 경로를 사용하는 페이지로부터 getStaticProps를 부를 때 (Static Stite Generation), Next.js는 getStaticProps에서 지정한 모든 경로를 정적으로 사전 렌더링 한다.

// pages/posts/[id].js

// Generates '/posts/1' and '/posts/2'
export async function getStaticPath() {
  return {
    path: [{ params: { id: '1'} }, { params: { id: '2'} }],
    fallback: false // can also be true or 'blocking'
  }
}

// getStaticPaths에는 getStaticProps를 사용해야한다.
export async function getStaticProps(context) {
  return {
    props: { post: {} },
  }
}

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

 

  • getStaticPaths 사용 방법
export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } // 밑에 나오는 paths 섹션을 참조하면 된다.
    ],
    fallback: true, false or 'blocking' // 밑에 나오는 fallback 섹션을 참조하면 된다.
  }
}

 

 

  • getStaticPaths 반환 값

  getStaticPaths는 다음과 같은 필수 속성이 있는 객체를 반환해야 한다.

1. paths

  paths key는 사전 렌더링할 경로를 결정한다. 예를 들어 pages/posts/[id].js라는 동적 경로를 사용하는 페이지가 있다고 가정한다. 이 페이지에서 getStaticPaths를 export 하고 paths에 대해 다음을 반환하는 경우는 아래와 같다.

return {
  paths: [
    { params: { id: '1' }},
    {
      params: { id: '2' },
      locale: "en",
    },
    fallback: ...
  }
}

 

  그러면 Next.js는 pages/posts/[id].js의 page 컴포넌트를 사용하는 next build 동안에 /posts/1과 /posts/2를 정적으로 생성한다. 만약 페이지 이름이 pages/posts/[postId]/[commentId]이면 params에 postId와 commentId가 포함되어야 한다. 또 페이지 이름이 pages/[...slug]와 같은 포괄 경로를 사용하는 경우에는 params에 slug(배열)을 포함해야 한다. 만약 이 배열이 ['hello', 'world']인 경우 Next.js는 /hello/world에 페이지를 정적으로 생성한다. 마지막으로 페이지가 catch-all route 옵션을 사용할 경우 null, [], undefined 또는 false를 사용하여 최상위 경로를 렌더링 한다. 예를 들어서 pages/[[...slug]]에 slug: false를 제공하면, Next.js는 '/'페이지를 정적으로 생성할 것이다.

  params 문자열은 대소문자를 구분하여 이상적으로는 경로가 올바르게 생성되도록 정규화되어야 한다. 예를 들어 파라미터에서 WoRLD가 반환되면 WoRLD가 실제로 방문한 경로인 경우에만 일치한다. world나 World는 안된다. 

  params 객체와는 별도로 i18n이 구성될 때는 생성되는 경로에 대한 로케일을 구성하는 로케일 필드가 반환될 수도 있다.

 

2. fallback : false

  fallback이 false이면 getStaticProps에 의해 반환되지 않은 paths는 404페이지가 된다. next build가 실행될 때 Next.js는 getStaticPaths가 fallback: false를 반환되었는지 확인하고 getStaticPaths에 반환된 경로만 빌드한다. 이 옵션은 생성할 경로 수가 적거나 새 페이지 데이터가 자주 추가되지 않은 경우에 유용하다. 더 많은 경로를 추가해야 하고 fallback: false가 있는 경우 새 경로를 생성할 수 있도록 next build를 다시 실행해야 한다.

  다음 예제는 pages/posts/[id].js라는 페이지 당 하나의 블로그 게시물을 사전 렌더링한다. 블로그 게시물 목록은 CMS에서 가져와서 getStaticPaths에서 반환한다. 그런 다음 각 페이지에 대해 getStaticProps를 사용하여 CMS에서 게시물 데이터를 가져온다.

// pages/posts/[id].js

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

// 이 함수는 빌드 시 호출된다.
export async function getStaticPaths() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()
  
  // 게시물을 기반으로 미리 렌더링하려는 경로를 가져온다.
  const paths = posts.map((post) => ({
    params: { id: post.id },
  }))
  
  // 빌드 시 이 경로만 미리 렌더링된다.
  // { fallback: false }는 paths 경로가 아닌 경우 404여야 함을 의미한다.
  return { paths, fallback: false }
}

// 이 함수 역시 빌드 시 호출된다.
export async function getStaticProps({ params }) {
  // params는 포스트 'id'를 포함한다.
  // 만약 경로가 /posts/1 인 경우 params.id는 1이다.
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()
  
  return { props: { posts } }
}

export default Post

 

3. fallback: true

  fallback이 true이면 getStaticProps의 동작이 다음과 같이 변경된다. 먼저 getStaticPaths에서 반환된 경로는 getStaticProps에 의해 빌드 시 HTML로 렌더링 된다. 다음으로 빌드 시 생성되지 않은 경로여도 404 페이지를 생성하지 않는다. 대신 Next.js는 그러한 경로에 대한 첫 번째 요청에서 페이지의 대체 버전을 제공한다. Google과 같은 웹 크롤러에는 fallback이 제공되지 않으며 대신 fallback: 'blocking'과 같이 동작한다. 

 셋째로 fallback: true를 사용한 페이지 일 때 next/link 또는 next/router을 통해서 탐색하는 경우(Client Side), Next.js는 fallback을 제공하지 않고 대신 페이지가 fallbakc: 'blocking'과 같이 작동한다. 또 백그라운드에서 Next.js는 요청된 경로인 HTML과 JSON을 정적으로 생성한다. 이것은 getStaticProps를 실행하는 것을 포함한다.

  마지막으로 완료되면 브라우저는 생성된 경로에 대한 JSON을 수신한다. 이것은 필요한 props로 페이지를 자동으로 렌더링 하는 데 사용된다. 사용자 관점에서 페이지는 대체 페이지에서 전체 페이지로 교체된다.

  동시에 Next.js는 사전 렌더링된 페이지 목록에 이 경로를 추가한다. 동일한 경로에 대한 후속 요청은 빌드 시 사전 렌더링된 다른 페이지와 같이 생성된 페이지를 제공한다. 

 

  fallbakc: true는 앱에 데이터에 의존하는 정적 페이지가 매우 많은 경우 (예: 대규모 전자상거래 사이트)에 유용하다. 모든 제품 페이지를 사전 렌더링하려면 빌드 시간이 매우 오래 걸리기 때문이다.

  대신 페이지의 작은 하위 집합을 정적으로 생성하고 나머지를 위해 fallback: true를 사용할 수 있다. 누군가 아직 생성되지 않은 페이지를 요청하면 사용자는 로딩 표시기 또는 스켈레톤 컴포넌트가 있는 페이지를 보게 된다.

  잠시 후 getStaticProps가 완료된고 요청된 데이터로 페이지가 렌더링 된다. 이제부터는 동일한 페이지를 요청하는 모든 사람은 정적으로 미리 렌더링 된 페이지를 보게 된다. 이를 통해 빠른 빌드와 정적 생성의 이점을 유지하면서 사용자는 항상 빠른 경험을 할 수 있다.

'Next.js' 카테고리의 다른 글

Next.js 4-3 getStaticPaths  (0) 2023.04.24
Next.js 4-2. getStaticPaths  (0) 2023.04.24
Next.js 3-2. getStaticProps (SSG)  (0) 2023.04.21
Next.js 3-1. getStaticProps (SSG)  (0) 2023.04.21
Next.js 2-2. getServerSideProps(SSR)  (0) 2023.04.19