정확한 세그먼트 이름을 미리 알지 못하고 동적 데이터에서 경로를 생성하려는 경우 요청 시 채워지거나 빌드 시 미리 렌더링되는 동적 세그먼트를 사용할 수 있습니다.
Convention
동적 세그먼트는 폴더 이름을 대괄호로 묶음으로써 생성할 수 있습니다: [folderName]. 예를 들어 [id] 또는 [slug]입니다. 동적 세그먼트는 레이아웃, 페이지, 경로 및 generateMetadata 함수에 params 소품으로 전달됩니다.
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 */
import React from "react";
interface Post {
createdAt: string;
name: string;
avatar: string;
slug: string;
}
interface PageProps {
params: { slug: Post["slug"] };
}
export async function generateStaticParams() {
const posts: Post[] = await fetch(`${process.env.MOCK_API_URL}/posts`).then(
(res) => res.json()
);
return posts.map((post) => ({
slug: post.slug,
}));
}
const Page = ({ params }: PageProps) => {
return <div>{JSON.stringify(params)}</div>;
};
export default Page;
위 코드를 가진 프로젝트를 yarn build 하면 아래 그림 처럼 ${process.env.MOCK_API_URL}/posts 의 데이터를 미리 호출한 정적 페이지가 생성된것 을 볼 수 있습니다.
또한 generateStaticParams 함수의 주요 이점은 데이터를 스마트하게 관리 하다는 것 입니다. generateStaticParams 함수 내에서 fetch 요청을 사용하여 동일한 콘텐츠를 가져오는 경우 자동으로 중복 제거됩니다. 이는 여러 generateStaticParams, 레이아웃 및 페이지에서 동일한 인수를 가진 fetch 요청이 한 번만 실행되므로 빌드 시간을 단축합니다.
Catch-all Segments
[...folderName] 괄호 안에 줄임표를 추가하여 동적 세그먼트를 모든 후속 세그먼트로 확장할 수 있습니다.
예를 들어 app/shop/[...slug]/page.js는 /shop/clothes와 일치하지만 /shop/clothes/tops, /shop/clothes/tops/t-shirts 등과도 일치합니다.
Route | Example | 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'] } |
Optional Catch-all Segments
포괄적인 세그먼트는 [[...folderName]]과 같이 이중 대괄호 안에 매개 변수를 포함하여 옵션으로 만들 수 있습니다.
예를 들어 app/shop/[[...slug]]/page.js는 /shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts 외에도 /shop과도 일치합니다.
Route | Example | 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'] } |
Typescript
TypeScript를 사용할 때 구성된 라우트 세그먼트에 따라 매개변수 유형을 추가할 수 있습니다.
Route | params Type Definition |
app/blog/[slug]/page.js | { slug: string } |
app/shop/[...slug]/page.js | { slug: string[] } |
app/[categoryId]/[itemId]/page.js | { categoryId: string, itemId: string } |
Playground
느낀점
동적 라우트라도 generateStaticParams함수를 사용하면 빌드 시 정적파일로 미리 생성할 수 있어서 고급화된 사용자 접근 시나리오를 구현 할 수 있어보입니다. 예를 들어 인기글이나 사용자 접근이 많은 상세페이지 30개 정도만 미리 정적 페이지를 만들어 두면 사용자 경험이 좋아질 것 입니다.
참조
'기억보단 기록을 > Next JS (App Router)' 카테고리의 다른 글
[NextJS 13] Routing - Error Handling(에러처리) (0) | 2023.06.10 |
---|---|
[NextJS 13] Routing - Loading UI and Streaming (0) | 2023.06.07 |
[NextJS 13] Routing - Route Groups (0) | 2023.06.04 |
[NextJS 13] Routing - Linking and Navigating (0) | 2023.06.03 |
[NextJS 13] Routing - Pages and Layouts (1) | 2023.05.31 |