๋ฐ˜์‘ํ˜•

TL;DR


  • [slug] : ๋‹จ์ผ ๊ฒฝ๋กœ ์„ธ๊ทธ๋จผํŠธ ํฌ์ฐฉ
  • [...slug] : ๋‹ค์ค‘ ๊ฒฝ๋กœ ์„ธ๊ทธ๋จผํŠธ ํฌ์ฐฉ(Catch-All)
  • [[...slug]] : ๋ฃจํŠธ ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ํฌ์ฐฉ(Optional Catch-All)

 

 

Dynamic Segments


์ •ํ™•ํ•œ ์„ธ๊ทธ๋จผํŠธ ์ด๋ฆ„์„ ๋ฏธ๋ฆฌ ์•Œ ์ˆ˜ ์—†์„ ๋•Œ ํด๋” ์ด๋ฆ„์„ ๋Œ€๊ด„ํ˜ธ๋กœ ๊ฐ์‹ธ๋ฉด ๋‹ค์ด๋‚˜๋ฏน ์„ธ๊ทธ๋จผํŠธ๋กœ ์ž‘๋™. ์„ธ๊ทธ๋จผํŠธ ์ด๋ฆ„์€ layout, page ๋˜๋Š” route ํŒŒ์ผ์—์„œ params ํ”„๋กญ์œผ๋กœ ๊ฐ’ ์กฐํšŒ ๊ฐ€๋Šฅ.

 

Route URL Example Params
app/blog/[slug]/page.js /blog/a { slug: 'a' }
app/blog/[slug]/page.js /blog/b { slug: 'b' }
๋ฃจํŠธ ๊ฒฝ๋กœ(blog/)์— ํŽ˜์ด์ง€ ์—†์œผ๋ฉด ์ ‘๊ทผ ๋ถˆ๊ฐ€.

 

 

Catch-all Segments


๋‹ค์ด๋‚˜๋ฏน ์„ธ๊ทธ๋จผํŠธ๋ฅผ ํ™•์žฅํ•˜์—ฌ ๊ฒฝ๋กœ์˜ ์—ฌ๋Ÿฌ ์„ธ๊ทธ๋จผํŠธ๋ฅผ ํฌ์ฐฉํ•˜๋ ค๋ฉด ํด๋” ์ด๋ฆ„ ์•ž์— ์  3๊ฐœ(โ€ฆ)๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ Catch-All ์„ธ๊ทธ๋จผํŠธ๋กœ ์„ค์ • ๊ฐ€๋Šฅ. ์ด๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๊ฒฝ๋กœ๋ฅผ ํ•˜๋‚˜์˜ ์„ธ๊ทธ๋จผํŠธ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ params๋Š” ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ „๋‹ฌ๋จ.

 

Route URL Example Params
app/blog/[...slug]/page.js /blog/a { slug: ['a'] }
app/blog/[...slug]/page.js /blog/a/b { slug: ['a', 'b'] }
๋ฃจํŠธ ๊ฒฝ๋กœ(blog/)์— ํŽ˜์ด์ง€ ์—†์œผ๋ฉด ์ ‘๊ทผ ๋ถˆ๊ฐ€.

 

 

Optional Catch-all Segments


Catch-All ์„ธ๊ทธ๋จผํŠธ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์ ์šฉํ•  ๋• ๋Œ€๊ด„ํ˜ธ 2๊ฐœ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Optional Catch-All ์„ธ๊ทธ๋จผํŠธ๋กœ ์„ค์ • ๊ฐ€๋Šฅ. ๋ฃจํŠธ ๊ฒฝ๋กœ์™€ ํ•˜์œ„ ๊ฒฝ๋กœ๋ฅผ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฃจํŠธ ๊ฒฝ๋กœ์—์„  params.slug ๊ฐ’์ด undefined๋กœ ์ „๋‹ฌ๋จ.

 

Route URL Example Params
app/blog/[[...slug]]/page.js /blog { slug: undefined }
app/blog/[[...slug]]/page.js /blog/a { slug: ['a'] }
app/blog/[[...slug]]/page.js /blog/a/b { slug: ['a', 'b'] }
๋ฃจํŠธ ๊ฒฝ๋กœ(blog/)๋กœ ์ ‘๊ทผํ•˜๋ฉด app/blog/[[...slug]]/page.js ๋กœ ๋งคํ•‘๋จ.
โš ๏ธ Optional Catch-All ์„ธ๊ทธ๋จผํŠธ ์‚ฌ์šฉ์‹œ ๋™์ผ ๋ฃจํŠธ ํด๋”์— ๋ณ„๋„์˜ ํŽ˜์ด์ง€ ํŒŒ์ผ์€ ์ถ”๊ฐ€ ๋ชปํ•จ
๐Ÿ“ฆ app/
โ””โ”€ blug/
โ”œโ”€ [[...slug]]/
โ”‚ โ””โ”€ page.tsx
โ””โ”€ page.tsx (โŒ ๋ถˆ๊ฐ€)

 

 

Generating Static Params


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

export async function generateStaticParams() {
// API ํ˜ธ์ถœ ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฟผ๋ฆฌ ๋“ฑ์œผ๋กœ ๋™์  ๊ฒฝ๋กœ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ด
const posts = await fetch('https://api.example.com/posts').then((res) => res.json());
return posts.map((post) => ({
slug: post.slug, // slug๋Š” ๋™์  ๊ฒฝ๋กœ ํŒŒ๋ผ๋ฏธํ„ฐ์— ํ•ด๋‹น
}));
}
export default function Page({ params }) {
return <div>Post: {params.slug}</div>;
}

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€

๋Œ“๊ธ€์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.