본문 바로가기

Next.js

Next.js 11-5 Routing Dynamic Routes

  정확한 세그먼트 이름을 미리 알지 못하고 동적 데이터에서 경로를 생성하는 경우 요청 시 채워지거나 빌드 시 사전 렌더링되는 동적 세그먼트를 사용할 수 있다.

 

  • Convention

  동적 세그먼트는 폴더 이름을 대괄호로 묶음으로써 생성할 수 있다. (예: [folderName]). 예를 들어 [id] 또는 [slug]이다. 동적 세그먼트는 layout, page, route와 generateMetadata 함수에 params prop으로 전달된다.

 

  • Example

  예를 들어 블로에는 app/blog/[slug]/page.js 경로가 포함될 수 있다. 여기서 [slug]는 블로그 게시물의 동적 세그먼트이다.

// app/blog/[slug]/page.js

export default function Page({ params }) {
  return <div>My Post</div>
}
Route Example URL params
app/blog/[slug]/page.js /blog/a { slug: 'a' }
app/blog/[slug]/page.js /blog/b { slug: 'b' }
app/blog/[slug]/page.js /blog/c { slug: 'c' }

 

  • Generating Static Params

  generateStaticParams 함수는 동적 경로 세그먼트와 함께 사용되어 요청 시, 요청 때가 아닌 빌드 때 경로를 정적으로 생성할 수 있다.

// app/blog/[slug]/page.tsx

export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json());
  
  return posts.map((post) => ({
    slug: post.slugm
  }));
}

 

   generateStaticParams 함수의 주요 이점은 스마트한 데이터 검색이다. 가져오기 요청을 사용하여 generateStaticParams 함수 내에서 콘텐츠를 가져오면 요청이 자동으로 중복 제거된다. 이는 여러 generateStaticParams, 레이아웃 및 페이지에서 동일한 인수를 사용하는 가져오기 요청이 한 번만 이뤄지므로 빌드 시간이 단축됨을 의미한다.

 

  • Catch-all Segments

  [...folderName] 괄호 안에 줄임표를 추가하여 동적 세그먼트를 모든 후속 세그먼트로 확장할 수 있다. 예를 들어 app/shop/[...slug]/page.js는 /shop/clothes와 일치하지만 shop/clothes/tops, /shop/clothes/tops/t-shirts 등과도 일치한다.

Route Example URL params
app/blog/[...slug]/page.js /shop/a { slug: ['a'] }
app/blog/[...slug]/page.js /shop/a/b { slug: ['a', 'b'] }
app/blog/[...slug]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

 

  • Optional Catch-all Segments

  포괄적인 세그먼트는 [[...folderName]]과 같이 이중 대괄호 안에 매개 변수를 포함하여 옵션으로 만들 수 있다. 예를 들어 app/shop/[[...slug]]/page.js는 /shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts 외에도 /shop과도 일치한다. catch-all 세그먼트와 선택적 catch-all 세그먼트의 차이점은 optional을 사용하면 매개변수가 없는 경로도 일치한다는 것이다.(예: /shop)

Route Example URL params
app/blog/[[...slug]]/page.js /shop {}
app/blog/[[...slug]]/page.js /shop/a { slug: ['a'] }
app/blog/[[...slug]]/page.js /shop/a/b { slug: ['a', 'b'] }
app/blog/[[...slug]]/page.js /shop/a/b/c { slug: ['a', 'b', 'c'] }

 

  • TypeScript

  TypeScript를 사용할 때 구성된 경로 세그먼트에 따라 매개변수 유형을 추가할 수 있다.

// app/blog/[slug]/page.tsx

export default function Page({ params: { slug: string }}) {
  return <h1>My Page</h1>;
}
Route params
app/blog/[slug]/page.js { slug: string }
app/blog/[...slug]/page.js { slug: string[] }
app/[categoryId]/[itemId]/page.js { categoryId: string, itemId: string }