Dynamic Routes

동적 라우트를 사용하면 동적 데이터를 기반으로 프로그래매틱하게 라우트 세그먼트를 생성할 수 있습니다.

Convention

규칙

동적 세그먼트는 폴더 이름을 대괄호로 감싸서 만들 수 있습니다: [folderName]. 예를 들어, [id] 또는 [slug].

동적 세그먼트는 params prop으로 layout, page, route, 및 generateMetadata 함수에 전달됩니다.

Example

예제

예를 들어, 블로그는 [slug]가 블로그 게시물의 동적 세그먼트인 app/blog/[slug]/page.js 라우트를 포함할 수 있습니다.

app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>
}
app/blog/[slug]/page.js
export default function Page({ params }) {
  return <div>My Post: {params.slug}</div>
}
RouteExample URLparams
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' }

세그먼트에 대한 params를 생성하는 방법은 generateStaticParams() 페이지를 참조하세요.

참고: 동적 세그먼트는 pages 디렉토리의 동적 라우트와 동일합니다.

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.slug,
  }))
}
app/blog/[slug]/page.js
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}

generateStaticParams 함수의 주요 이점은 데이터의 스마트한 검색입니다. generateStaticParams 함수 내에서 fetch 요청을 사용하여 콘텐츠를 검색하면 요청이 자동으로 메모이제이션됩니다. 즉, 여러 generateStaticParams, 레이아웃 및 페이지에서 동일한 인수를 사용하는 fetch 요청은 한 번만 수행되어 빌드 시간을 단축합니다.

pages 디렉토리에서 마이그레이션하는 경우 마이그레이션 가이드를 사용하세요.

더 많은 정보와 고급 사용 사례는 generateStaticParams 서버 함수 문서를 참조하세요.

Catch-all Segments

Catch-all 세그먼트

동적 세그먼트는 대괄호 안에 줄임표를 추가하여 모든 후속 세그먼트를 포괄하도록 확장할 수 있습니다: [...folderName].

예를 들어, app/shop/[...slug]/page.js/shop/clothes뿐만 아니라 /shop/clothes/tops, /shop/clothes/tops/t-shirts 등에도 일치합니다.

RouteExample URLparams
app/shop/[...slug]/page.js/shop/a{ slug: ['a'] }
app/shop/[...slug]/page.js/shop/a/b{ slug: ['a', 'b'] }
app/shop/[...slug]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }

Optional Catch-all Segments

선택적 Catch-all 세그먼트

Catch-all 세그먼트는 매개변수를 이중 대괄호로 포함하여 선택 사항으로 만들 수 있습니다: [[...folderName]].

예를 들어, app/shop/[[...slug]]/page.js/shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts뿐만 아니라 /shop과도 일치합니다.

catch-alloptional catch-all 세그먼트의 차이점은 optional의 경우 매개변수 없이도 경로가 일치한다는 점입니다(위 예제의 /shop).

RouteExample URLparams
app/shop/[[...slug]]/page.js/shop{}
app/shop/[[...slug]]/page.js/shop/a{ slug: ['a'] }
app/shop/[[...slug]]/page.js/shop/a/b{ slug: ['a', 'b'] }
app/shop/[[...slug]]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }

TypeScript

TypeScript

TypeScript를 사용할 때, 구성된 경로 세그먼트에 따라 params에 대한 타입을 추가할 수 있습니다.

app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
  return <h1>My Page</h1>
}
app/blog/[slug]/page.js
export default function Page({ params }) {
  return <h1>My Page</h1>
}
Routeparams Type Definition
app/blog/[slug]/page.js{ slug: string }
app/shop/[...slug]/page.js{ slug: string[] }
app/shop/[[...slug]]/page.js{ slug?: string[] }
app/[categoryId]/[itemId]/page.js{ categoryId: string, itemId: string }

참고: 이는 TypeScript 플러그인에 의해 자동으로 수행될 수 있습니다.