Dynamic Routes(๋์ ๊ฒฝ๋ก)
์ ํํ ์ธ๊ทธ๋จผํธ ์ด๋ฆ์ ๋ฏธ๋ฆฌ ์์ง ๋ชปํ๊ณ ๋์ ๋ฐ์ดํฐ๋ก ๊ฒฝ๋ก๋ฅผ ์์ฑํ๋ ค๋ ๊ฒฝ์ฐ, ์์ฒญ ์ ์ฑ์์ง๊ฑฐ๋ ๋น๋ ์ ๋ฏธ๋ฆฌ ๋ ๋๋ง๋๋ ๋์ ์ธ๊ทธ๋จผํธ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
1. Convention(๊ท์น)
๋์ ์ธ๊ทธ๋จผํธ๋ ํด๋์ ์ด๋ฆ์ ๋๊ดํธ๋ก ๋ฌถ์ด ๋ง๋ค ์ ์์ต๋๋ค: [ํด๋ ์ด๋ฆ]. e.g. [id] ๋๋ [slug].
๋์ ์ธ๊ทธ๋จผํธ๋ layout, page, route ๋ฐ ์์ฑ ๋ฉํ๋ฐ์ดํฐ ํจ์์ params ํ๋กํผํฐ๋ก ์ ๋ฌ๋ฉ๋๋ค.
2. ์์
์๋ฅผ ๋ค์ด, ๋ธ๋ก๊ทธ๊ฐ app/blog/[slug]/page.js ๋ผ๋ ๊ฒฝ๋ก๋ฅผ ํฌํจํ ๊ฒฝ์ฐ, ์ฌ๊ธฐ์ [slug]๊ฐ ๋ธ๋ก๊ทธ ๊ฒ์๊ธ์ ๋์ ์ธ๊ทธ๋จผํธ์
๋๋ค.
1export default function Page({ params }: { params: { slug: string } }) {2return <div>My Post: {params.slug}</div>3}
| 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' } |
์ธ๊ทธ๋จผํธ์ ๋ํ ํ๋ผ๋ฏธํฐ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๋ ค๋ฉด generate Static Params(์ ์ ํ๋ผ๋ฏธํฐ ์์ฑ) ์ ์ ์ฐธ์กฐํ์ธ์.
์ฐธ๊ณ : ๋์ ์ธ๊ทธ๋จผํธ๋
pages๋๋ ํ ๋ฆฌ์ ๋์ ๋ผ์ฐํธ์ ๋์ผํฉ๋๋ค.
3. ์ ์ ํ๋ผ๋ฏธํฐ ์์ฑ
generateStaticParams ํจ์๋ ๋์ ๊ฒฝ๋ก ์ธ๊ทธ๋จผํธ์ ํจ๊ป ์ฌ์ฉํ์ฌ ์์ฒญ ์, ์จ๋๋งจ๋๊ฐ ์๋ ๋น๋ ์์ ์ ๊ฒฝ๋ก๋ฅผ ์ ์ ์ผ๋ก ์์ฑํ ์ ์์ต๋๋ค.
1export async function generateStaticParams() {2const posts = await fetch('https://.../posts').then(res => res.json())34return posts.map(post => ({5slug: 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, ๋ฑ๊ณผ๋ ์ผ์นํฉ๋๋ค.
| 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'] } |
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).
| 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'] } |
6. TypeScript
TypeScript๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๊ตฌ์ฑ๋ ๋ผ์ฐํธ ์ธ๊ทธ๋จผํธ์ ๋ฐ๋ผ params์ ๋ํ ํ์
์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
1export default function Page({ params }: { params: { slug: string } }) {2return <h1>My Page</h1>3}
| 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 } |
์ฐธ๊ณ : ์ด ๊ธฐ๋ฅ์ ํฅํ TypeScript plugin์ ์ํด ์๋์ผ๋ก ์ฒ๋ฆฌ๋ ์ ์์ต๋๋ค.