동적 라우트
생성일: 2024-03-04
수정일: 2024-03-04
정확한 세그먼트 이름을 미리 알 수 없고 동적 데이터로 경로를 생성하려는 경우 요청 시 결정되거나 빌드 시 미리 렌더링되는 동적 세그먼트를 사용한다.
컨벤션
동적 세그먼트는 폴더의 이름을 대괄호로 묶어 만들 수 있다: [folderName]
. 예: [id]
또는 [slug]
.
동적 세그먼트는 layout
, page
, route
및 generateMetadata
함수에 매개변수로 전달된다.
예시
예를 들어 블로그에는 다음과 같은 경로 app/blog/[slug]/page.js
가 포함될 수 있으며, 여기서 [slug]
는 블로그 게시글의 동적 세그먼트다.
// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>;
}
라우트 | 예시 URL | 파라미터 |
---|---|---|
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' } |
Tip
동적 세그먼트는 pages
디렉토리의 동적 라우트와 동일하다.
정적 파라미터 생성하기
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,
}));
}
generateStaticParams
함수의 가장 큰 장점은 데이터를 스마트하게 검색할 수 있다는 점이다. fetch
요청을 사용하여 generateStaticParams
함수 내에서 콘텐츠를 가져오면 요청이 자동으로 캐시된다. 즉, 여러 generateStaticParams
, 레이아웃 및 페이지에 걸쳐 동일한 인자를 사용하는 fetch
요청은 한 번만 수행되므로 빌드 시간이 단축된다.
자세한 내용 및 고급 사용 사례는 generateStaticParams
서버 함수 문서를 참조한다.
Catch-all 세그먼트
동적 세그먼트는 괄호 안에 [...folderName]
줄임표를 추가하여 모든 후속 세그먼트를 포함하도록 확장할 수 있다.
예를 들어 app/shop/[...slug]/page.js
는 /shop/clothes
뿐만 아니라 /shop/clothes/tops
, /shop/clothes/tops/t-shirts
등과도 일치한다.
라우트 | 예시 URL | 파라미터 |
---|---|---|
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'] } |
선택적 Catch-all 세그먼트
캐치올 세그먼트는 파라미터를 이중 대괄호 안에 포함하여 선택 사항으로 만들 수 있다: [[...folderName]]
.
예를 들어 app/shop/[[...slug]]/page.js
는 /shop/clothes
, /shop/clothes/tops
, /shop/clothes/tops/t-shirts
외에도 /shop
과도 일치한다.
캐치올 세그먼트와 선택적 캐치올 세그먼트의 차이점은 후자의 경우 파라미터가 없는 경로도 일치한다는 것이다(위 예제에서는 /shop
).
라우트 | 예시 URL | 파라미터 |
---|---|---|
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'] } |
타입스크립트
타입스크립트를 사용하는 경우, 구성된 라우트 세그먼트에 따라 params
타입을 추가할 수 있다.
// app/blog/[slug]/page.tsx
export default function Page({ params }: { params: { slug: string } }) {
return <h1>My Page</h1>;
}
라우트 | 파라미터 |
---|---|
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 } |
Tip
이 작업은 향후 TypeScript 플러그인에 의해 자동으로 수행될 수 있다.