๐ŸŽ‰ berenickt ๋ธ”๋กœ๊ทธ์— ์˜จ ๊ฑธ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๐ŸŽ‰
Front
NextJs
09-Dynamic Routes

Dynamic Routes(๋™์  ๊ฒฝ๋กœ)

์ •ํ™•ํ•œ ์„ธ๊ทธ๋จผํŠธ ์ด๋ฆ„์„ ๋ฏธ๋ฆฌ ์•Œ์ง€ ๋ชปํ•˜๊ณ  ๋™์  ๋ฐ์ดํ„ฐ๋กœ ๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, ์š”์ฒญ ์‹œ ์ฑ„์›Œ์ง€๊ฑฐ๋‚˜ ๋นŒ๋“œ ์‹œ ๋ฏธ๋ฆฌ ๋ Œ๋”๋ง๋˜๋Š” ๋™์  ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


1. Convention(๊ทœ์น™)

๋™์  ์„ธ๊ทธ๋จผํŠธ๋Š” ํด๋”์˜ ์ด๋ฆ„์„ ๋Œ€๊ด„ํ˜ธ๋กœ ๋ฌถ์–ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: [ํด๋” ์ด๋ฆ„]. e.g. [id] ๋˜๋Š” [slug].

๋™์  ์„ธ๊ทธ๋จผํŠธ๋Š” layout, page, route ๋ฐ ์ƒ์„ฑ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ•จ์ˆ˜์— params ํ”„๋กœํผํ‹ฐ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.


2. ์˜ˆ์‹œ

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ธ”๋กœ๊ทธ๊ฐ€ app/blog/[slug]/page.js ๋ผ๋Š” ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•  ๊ฒฝ์šฐ, ์—ฌ๊ธฐ์„œ [slug]๊ฐ€ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๊ธ€์˜ ๋™์  ์„ธ๊ทธ๋จผํŠธ์ž…๋‹ˆ๋‹ค.

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

์„ธ๊ทธ๋จผํŠธ์— ๋Œ€ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋ ค๋ฉด generate Static Params(์ •์  ํŒŒ๋ผ๋ฏธํ„ฐ ์ƒ์„ฑ) ์ ˆ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ฐธ๊ณ : ๋™์  ์„ธ๊ทธ๋จผํŠธ๋Š” pages ๋””๋ ‰ํ† ๋ฆฌ์˜ ๋™์  ๋ผ์šฐํŠธ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.


3. ์ •์  ํŒŒ๋ผ๋ฏธํ„ฐ ์ƒ์„ฑ

generateStaticParams ํ•จ์ˆ˜๋Š” ๋™์  ๊ฒฝ๋กœ ์„ธ๊ทธ๋จผํŠธ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ์‹œ, ์˜จ๋””๋งจ๋“œ๊ฐ€ ์•„๋‹Œ ๋นŒ๋“œ ์‹œ์ ์— ๊ฒฝ๋กœ๋ฅผ ์ •์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

app/blog/[slug]/page.tsx
1
export async function generateStaticParams() {
2
const posts = await fetch('https://.../posts').then(res => res.json())
3
4
return posts.map(post => ({
5
slug: post.slug,
6
}))
7
}

generateStaticParams ํ•จ์ˆ˜์˜ ์ฃผ์š” ์ด์ ์€ ํšจ์œจ์ ์ธ ๋ฐ์ดํ„ฐ ์š”์ฒญ์ž…๋‹ˆ๋‹ค. Fetch ์š”์ฒญ์„ ์‚ฌ์šฉํ•˜์—ฌ generateStaticParams ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ฝ˜ํ…์ธ ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ, ์š”์ฒญ์€ ์ž๋™์œผ๋กœ ์ค‘๋ณต ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์—ฌ๋Ÿฌ generateStaticParams, ๋ ˆ์ด์•„์›ƒ ๋ฐ ํŽ˜์ด์ง€์— ๊ฑธ์ณ ๋™์ผํ•œ ์ธ์ž๋ฅผ ๊ฐ€์ง„ ์ค‘๋ณต๋œ fetch ์š”์ฒญ์€ ํ•œ ๋ฒˆ๋งŒ ์ˆ˜ํ–‰๋˜๋ฏ€๋กœ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋ฉ๋‹ˆ๋‹ค.

Pages ๋””๋ ‰ํ† ๋ฆฌ๋กœ๋ถ€ํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ํ•„์š”ํ•˜๋ฉด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๋” ๋งŽ์€ ์ •๋ณด ๋ฐ ํ™œ์šฉ ์‚ฌ๋ก€๋Š” generateStaticParams server function documentation๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.


4. Catch-all(ํฌ๊ด„) Segments

๋™์  ์„ธ๊ทธ๋จผํŠธ๋Š” ๊ด„ํ˜ธ [...ํด๋”๋ช…] ์•ˆ์— ์ค„์ž„ํ‘œ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ catch-all ํ›„์† ์„ธ๊ทธ๋จผํŠธ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, 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'] }

5. Optional Catch-all Segments

Catch-all ์„ธ๊ทธ๋จผํŠธ๋Š” ์ด์ค‘ ๋Œ€๊ด„ํ˜ธ ์•ˆ์— ๋งค๊ฐœ๋ณ€์ˆ˜์ธ [[...ํด๋”๋ช…]]์„ ํฌํ•จํ•˜์—ฌ ์„ ํƒ์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, app/shop/[[...slug]]/page.js ๋Š” /shop/clothes, /shop/clothes/tops, /shop/clothes/tops/t-shirts ์ด์™ธ์—๋„ /shop ๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

catch-all ๊ณผ optional 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'] }

6. TypeScript

TypeScript๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ตฌ์„ฑ๋œ ๋ผ์šฐํŠธ ์„ธ๊ทธ๋จผํŠธ์— ๋”ฐ๋ผ params์— ๋Œ€ํ•œ ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

app/blog/[slug]/page.tsx
1
export default function Page({ params }: { params: { slug: string } }) {
2
return <h1>My Page</h1>
3
}
Routeparams 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 }

์ฐธ๊ณ : ์ด ๊ธฐ๋Šฅ์€ ํ–ฅํ›„ TypeScript plugin์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.