미리 세그먼트의 정확한 이름을 알지 못하거나 다이나믹 데이터를 바탕으로 라우트를 만들고 싶다면 리퀘스트 타임이나 빌드 타임 때 프리렌더링 과정에서 생성 되는 다이나믹 세그먼트를 사용하면 좋다.
다이나믹 세그먼트는 폴더 이름을 대괄호로 감싸 구현할 수 있다. [폴더 이름]
예를 들어 [id]
혹은 [slug]
다이나믹 세그먼트는 layout
, page
, route
그리고 generateMetadata
함수에 params
프롭으로 전달 된다.
예를 들어 블로그 어플리케이션에 app/blog/[slug]/page.js
라우트가 있고 [slug]
값이 블로그 포스트를 위한 다이나믹 세그먼트라고 생각해보자.
export default function Page({ params }: { params: { slug: string } }) {
return <div>My Post: {params.slug}</div>
}
라우트 | 예시 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" } |
generateStaticParams() 페이지에서 세그먼트를 위한 params를 어떻게 생성할 수 있는지 알아보세요.
추천 사항:
다이나믹 세그먼트는pages
디렉토리의 Dynamic Routes와 동일한 개념이다.
generateStaticParams
함수는 다이나믹 라우트 세그먼트와 라우트 정적 생성 기능을 합친 것으로 리퀘스트 타임에 온디맨드로 실행되지 않고 빌드 타임에 실행 된다.
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
서버 함수 문서를 확인하여 더 많은 정보와 고급 예제를 살펴보세요.
다이나믹 세그먼트는 대괄호 내부에 줄임표를 붙여([...폴더 이름]
) 후속 세그먼트를 모두 잡아낼 수 있도록 확장할 수 있다.
예를 들어 app/shop/[...slug]/page.js
는 /shop/clothes
와 매치되고 /shop/clothes/tops
, /shop/clothes/tops/t-shirts
와도 매치 된다.
라우트 | 예시 URL | params |
---|---|---|
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 세그먼트는 대괄호를 중첩하여([[...폴더 이름]]
) 선택적으로 파라미터를 포함시킬 수 있도록 할 수 있다.
예를 들어 app/shop/[[...slug]]/page.js
는 /shop
, /shop/clothes
, /shop/clothes/tops
, /shop/clothes/tops/t-shirts
모두와 매치 된다
catch-all 과 선택적 catch-all 세그먼트의 차이점은 선택적 catch-all 세그먼트의 경우 파라미터가 없는 라우터도 매치 된다는 점이다(위의 예제에선 /shop
)
라우트 | 예시 URL | params |
---|---|---|
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
의 타입을 지정할 수 있다.
export default function Page({ params }: { params: { slug: string } }) {
return <h1>My Page</h1>
}
라우트 | params 타입 정의 |
---|---|
app/blog/[slug]/page.js | { slug: string } |
app/shop/[...slug]/page.js | { slug: string[] } |
app/[categoryId]/[itemId]/page.js | { categoryId: string, itemId: string } |
참고 사항:
미래엔 타입스크립트 플러그인을 통해 자동으로 이루어질 예정입니다.