์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- HTML ํ์ผ๊ตฌ์กฐ
- JS
- jest
- javascript
- ์ฝ๋ฉ๋ ํ
- ์น ๋ธ๋ผ์ฐ์ ๋ ๋๋ง
- tanstack-query
- canvas image
- axios-mock-adapte
- ํ๋ก ํธ์๋
- canvas js
- canvas
- clone coding
- ๋ฐ๋๋ผ JS๋ก ํฌ๋กฌ ์ฑ ๋ง๋ค๊ธฐ
- typescript
- tailwindcss
- queryprovider
- negative margin
- ์ํ์ฝ๋ฉ
- ์ฝ์ฝ์ํก ํด๋ก ์ฝ๋ฉ
- ๋ ธ๋ง๋ ์ฝ๋
- CSS
- JAVA Script
- HTML
- ์ฝ๋ฉ์ผ๊ธฐ
- next.js
- ๋ฐ๋๋ผ JS๋ก ๊ทธ๋ฆผํ ๋ง๋ค๊ธฐ
- ๋ ธ๋ง๋์ฝ๋
- react
- ์น ๋ธ๋ผ์ฐ์ ๊ตฌ์กฐ
- Today
- Total
Coding Archive
[Next.js] Next.js์ Route Groups์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ด์ฉํ ์ธ์ฆ ๋ฐ ๊ฒฝ๋ก ์ถฉ๋ ๋ฌธ์ ํด๊ฒฐํ๊ธฐ ๋ณธ๋ฌธ
[Next.js] Next.js์ Route Groups์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ด์ฉํ ์ธ์ฆ ๋ฐ ๊ฒฝ๋ก ์ถฉ๋ ๋ฌธ์ ํด๊ฒฐํ๊ธฐ
์ฝ๋ฑ์ด 2024. 11. 13. 22:00
Next.js Route Groups์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ด์ฉํ ์ธ์ฆ ๋ฐ ๊ฒฝ๋ก ์ถฉ๋ ๋ฌธ์ ํด๊ฒฐ
Next.js์ app ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ์ Route Groups(๊ฒฝ๋ก ๊ทธ๋ฃน) ๊ธฐ๋ฅ์ ํ์ฉํ๋ค ๋ณด๋ฉด, ๊ฒฝ๋ก๋ฅผ ์ง๊ด์ ์ด๊ณ ์กฐ์ง์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์์ง๋ง ๋์ผํ URL ๊ฒฝ๋ก๋ก ํด์๋๋ ํ์ด์ง๋ฅผ ๋ ๊ฐ ์ด์ ๊ตฌ์ฑํ๊ฒ ๋๋ฉด ๊ฒฝ๋ก ์ถฉ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ํ์ด์ง๋ฅผ ๋ ๋๋งํ๋ ๊ณผ์ ์์ ๋ฐ์ํ ๋ฌธ์ ๋ฅผ ํธ๋ฌ๋ธ์ํ ํ ๊ณผ์ ๊ณผ ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ ์ ๊ทผ ์ ์ด ๋ฐฉ๋ฒ์ ๊ณต์ ํฉ๋๋ค.
๐ ๋ฌธ์ ์ํฉ
ํ๋ก์ ํธ์ ๋ฉ์ธ ํ์ด์ง(/)์์ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฝํ ์ธ ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ ํ์ต๋๋ค. ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ๋ณ๋์ ๊ฒฝ๋ก ๊ทธ๋ฃน์ ํ์ฉํด ๋ค์๊ณผ ๊ฐ์ด ๋๋ ํ ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ์ต๋๋ค.
src/
โโโapp/
โ โโโ (private)/
โ โ โโโ page.tsx // ๋ก๊ทธ์ธ ์ ๋ ๋๋ง๋ ํ์ด์ง
โ โโโ (public)/
โ โโโ page.tsx // ๋น๋ก๊ทธ์ธ ์ ๋ ๋๋ง๋ ํ์ด์ง
โโโ middleware.ts // ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ ๋ฏธ๋ค์จ์ด
- (public)/page.tsx: ๋น๋ก๊ทธ์ธ ์ํ์ ์ฌ์ฉ์์๊ฒ ๊ธฐ๋ณธ์ผ๋ก ๋ณด์ฌ์ค ํ์ด์ง(๋ก๊ทธ์ธ ์ ๋ ์ฝํ ์ธ )
- (private)/page.tsx: ๋ก๊ทธ์ธ๋ ์ํ์ ์ฌ์ฉ์์๊ฒ ๊ธฐ๋ณธ์ผ๋ก ๋ณด์ฌ์ค ํ์ด์ง(ํผ๋ ์ฝํ ์ธ )
-> ์ด๋ ๊ฒ ๋ ๊ฐ์ ๊ฒฝ๋ก ๊ทธ๋ฃน์ ์ฌ์ฉํด ๋ก๊ทธ์ธ ์ ๊ณผ ํ์ ์๋ก ๋ค๋ฅธ ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ ํ์ต๋๋ค. ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ / ๊ฒฝ๋ก๋ก ์ ์ํ๋ฉด (public)/page.tsx๊ฐ ๋ ๋๋ง๋๊ณ , ๋ก๊ทธ์ธ๋ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ๋๋ (private)/page.tsx๊ฐ ๋ ๋๋ง๋๋๋ก ํฉ๋๋ค.
โ ๏ธ ๋ฌธ์ ๋ฐ์: ๊ฒฝ๋ก ์ถฉ๋ ์ค๋ฅ
์์ ๊ฐ์ ๊ฒฝ๋ก ๊ทธ๋ฃน ์ค์ ์ ๋์ผํ URL์ ๊ฐ๋ฆฌํค๋ ๋ ๊ฐ์ ๋ณ๋ ฌ ๊ฒฝ๋ก ๊ทธ๋ฃน์ด ์์ฑ๋๊ธฐ ๋๋ฌธ์, Next.js์์ ์๋์ ๊ฐ์ ๊ฒฝ๋ก ์ถฉ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
Error: You cannot have two parallel pages that resolve to the same path.
Please check /(private)/page and /(public)/page.
๐คทโ๏ธ ์์ธ ๋ถ์
๊ณต์ ๋ฌธ์๋ฅผ ์ดํด๋ณด๋ Next.js์์๋ ๊ฒฝ๋ก ๊ทธ๋ฃน ์ด๋ฆ์ด URL์ ์ํฅ์ ์ฃผ์ง ์๊ณ , ๋จ์ํ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ํ ์ญํ ๋ง ํฉ๋๋ค. ์ฆ, (public)/page.tsx์ (private)/page.tsx๋ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ฒฝ๋ก ๊ทธ๋ฃน์ด์ง๋ง URL ์์์๋ ๋ ๋ค ๋์ผํ / ๊ฒฝ๋ก๋ก ํด์๋ฉ๋๋ค.
[์ฐธ๊ณ : https://nextjs.org/docs/app/building-your-application/routing/route-groups]
Next.js ๊ฒฝ๋ก ๊ทธ๋ฃน ๊ด๋ จ ์ฌํญ
- ๊ฒฝ๋ก ๊ทธ๋ฃน์ ์ด๋ฆ์ URL์ ์ํฅ์ ๋ฏธ์น์ง ์์
(public)์ (private)๋ URL ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ , Next.js ๋ด๋ถ์์ ๊ฒฝ๋ก๋ฅผ ๊ตฌ๋ถ(ํด๋๋ฅผ ์กฐ์งํํ๊ธฐ ์ํ ์ญํ )ํ๊ธฐ ์ํ ์ญํ ๋ง ํฉ๋๋ค. ๋ฐ๋ผ์, (public)/page.tsx์ (private)/page.tsx๋ ๋ชจ๋ ๋์ผํ / ๊ฒฝ๋ก๋ก ์ธ์๋ฉ๋๋ค. - ์ค๋ณต๋ ๊ฒฝ๋ก ์ค๋ฅ ๋ฐ์(๋ณ๋ ฌ ๊ฒฝ๋ก๋ ๋์ผํ URL์ ๊ฐ์ง ์ ์์)
๋์ผํ ๊ฒฝ๋ก์ ๋ํด ๋ ๊ฐ์ ํ์ด์ง๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ Next.js๋ ๊ฒฝ๋ก ์ถฉ๋์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. ๊ฒฝ๋ก ๊ทธ๋ฃน์ ์ด์ฉํด ๋๋ ํ ๋ฆฌ๋ฅผ ๊ตฌ์ฑํด๋, ๋์ผํ URL(/)์ ๋ ๊ฐ์ ํ์ด์ง๊ฐ ์กด์ฌํ ์ ์์ผ๋ฏ๋ก ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
โ ํด๊ฒฐ ๋ฐฉ๋ฒ: ๊ฒฝ๋ก ๊ทธ๋ฃน์ ๊ตฌ๋ถํ๊ณ ๋ฏธ๋ค์จ์ด๋ก ์ ๊ทผ ์ ์ดํ๊ธฐ
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ์ฌ ํน์ ๊ฒฝ๋ก์ ๋ํ ์ ๊ทผ์ ์ ์ดํ๋ ๋ฐฉ์์ ์ฑํํ์ต๋๋ค. ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ /feed์ ๊ฐ์ ๋ณดํธ ๊ฒฝ๋ก ์ ๊ทผ์ ์ ์ดํ ์ ์์์ผ๋ฉฐ, ํด๋ผ์ด์ธํธ ์ธก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ด ์๋ ์๋ฒ ์ธก์์ ์ฒ๋ฆฌํจ์ผ๋ก์จ ๋ณด์์ฑ๊ณผ ์ฑ๋ฅ ์ต์ ํ ํจ๊ณผ๋ฅผ ๋์์ ์ป์ ์ ์์์ต๋๋ค.
์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ์๊น?
1. ๋ณด์์ฑ: ํด๋ผ์ด์ธํธ ์ธก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ๊ณ
๋ง์ฝ layout.tsx ๋ page.tsx์์ ํ ํฐ ๊ฐ์ ๊ฐ์ ธ์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํตํด ํ์ด์ง ์ ๊ทผ์ ์ ์ดํ๋ ค ํ๋ค๋ฉด, ํด๋ผ์ด์ธํธ ์ธก์์ ์กฐ๊ฑด๋ถ๋ก ํ์ด์ง๋ฅผ ์จ๊ธฐ๋ ๋ฐฉ์์ด ๋ฉ๋๋ค. ์ด ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ ๋จ์ ์ ๊ฐ์ง๋๋ค.
- ํด๋ผ์ด์ธํธ์์ ์ฝํ ์ธ ๊ฐ ์ ์๋ผ๋ ๋ก๋๋ ์ ์์: ํด๋ผ์ด์ธํธ ์ธก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ์ด์ง๊ฐ ์ด๋ฏธ ๋ก๋๋ ์ดํ์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๊ฑฐ๋ ์จ๊น๋๋ค. ์ด ๊ณผ์ ์์ ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ์ฝํ ์ธ ์ ์ผ๋ถ๋ฅผ ์ ์๋ผ๋ ๋ณผ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
- ๋ณดํธ๊ฐ ํ์ํ ์ฝํ ์ธ ๋ฅผ ์์ ํ ์ฐจ๋จํ๊ธฐ ์ด๋ ค์: ํด๋ผ์ด์ธํธ ์ธก์์ ์ฝํ ์ธ ๋ฅผ ์กฐ๊ฑด๋ถ๋ก ๋ ๋๋งํ ๊ฒฝ์ฐ, ์ค์ ๋ก๋ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ํ์ด์ง๋ฅผ ์์ฒญํ๊ณ ๋ก๋ํ ํ์ ํด๋น ์ฝํ ์ธ ๊ฐ ์จ๊ฒจ์ง๊ฒ ๋ฉ๋๋ค. ์ด๋ ๋ณด์ ์ธก๋ฉด์์ ์์ ํ ์ ๊ทผ ์ ์ด๊ฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
๋ฐ๋ฉด, ๋ฏธ๋ค์จ์ด๋ ์๋ฒ ์ธก์์ ํด๋ผ์ด์ธํธ ์์ฒญ์ด ์ฒ๋ฆฌ๋๊ธฐ ์ ์ ์ ๊ทผ์ ์ ์ดํ๋ฏ๋ก, ๋ณดํธ๋ ํ์ด์ง์ ๋ํ ์์ฒญ ์์ฒด๋ฅผ ์ฐจ๋จํฉ๋๋ค. ํ ํฐ์ด ์๋ ์ฌ์ฉ์๋ ์๋ฒ ์ธก์์๋ถํฐ ๋ณดํธ๋ ์ฝํ ์ธ ์ ์ ๊ทผํ ์ ์๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
2. ์ฑ๋ฅ ์ต์ ํ: ๋ถํ์ํ ํ์ด์ง ๋ก๋๋ฅผ ๋ฐฉ์ง
ํด๋ผ์ด์ธํธ ์ธก์์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ๋ค๋ฉด, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ํ์ด์ง์ ์ ๊ทผํ ๋๋ ํ์ด์ง๊ฐ ๋ก๋๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด /feed ํ์ด์ง์ ์ ๊ทผํ ๋, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๋ ์ฝํ ์ธ ๋ก๋ ํ์์ผ ์ ๊ทผ์ด ์ ํ๋์๋ค๋ ๋ฉ์์ง๋ฅผ ๋ณด๊ฒ ๋ ์ ์์ต๋๋ค. ์ด ๋ฐฉ์์ ๋ ๊ฐ์ง ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํฉ๋๋ค.
- ๋ถํ์ํ ๋ฐ์ดํฐ ์์ฒญ: ํด๋ผ์ด์ธํธ๋ ์๋ฒ์์ ํด๋น ํ์ด์ง์ ๊ด๋ จ๋ ๋ฐ์ดํฐ์ ๋ฆฌ์์ค๋ฅผ ๋ฐ์์ค๊ฒ ๋์ด, ๋ถํ์ํ ๋คํธ์ํฌ ์์ฒญ๊ณผ ๋ฐ์ดํฐ ์ ์ก์ด ๋ฐ์ํฉ๋๋ค.
- ์ด๊ธฐ ๋ก๋ฉ ์ง์ฐ: ํ์ด์ง๋ฅผ ๋จผ์ ๋ก๋ํ ํ์ ์กฐ๊ฑด๋ถ๋ก ์ฝํ ์ธ ๋ฅผ ์จ๊ธฐ๊ธฐ ๋๋ฌธ์, ์ค์ ๋ก ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ์ ์๋ ํ์ด์ง์์๋ ๋ถ๊ตฌํ๊ณ ์ด๊ธฐ ๋ก๋ฉ์ด ๋ฐ์ํ์ฌ UX๊ฐ ์ ํ๋ฉ๋๋ค.
๋ฏธ๋ค์จ์ด๋ ์์ฒญ ๋จ๊ณ์์ ๋ฐ๋ก ๋ฆฌ๋๋ ์ ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ์ ์๋ ํ์ด์ง์ ๋ํด ๋ถํ์ํ ๋ก๋ฉ์ด ๋ฐ์ํ์ง ์์ต๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๋ /login๊ณผ ๊ฐ์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ฆ์ ๋ฆฌ๋๋ ์ ๋์ด ํ์ด์ง ๋ก๋ฉ๊ณผ ๋คํธ์ํฌ ์์ฒญ์ ์ต์ ํํ ์ ์์ต๋๋ค.
3. ์ผ๊ด๋ ์ฌ์ฉ์ ๊ฒฝํ: ๋น ๋ฅธ ๋ฆฌ๋๋ ์ ์ฒ๋ฆฌ
๋ฏธ๋ค์จ์ด๋ ์์ฒญ์ด ์๋ฒ์์ ์ฒ๋ฆฌ๋๋ ๋จ๊ณ์์ ํ ํฐ ์ ๋ฌด์ ๋ฐ๋ผ ์ฆ์ ๋ฆฌ๋๋ ์ ํ๋ฏ๋ก, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ๋ณดํธ๋ ํ์ด์ง์ ์ ๊ทผํ๋ ค ํ ๋ ๋น ๋ฅด๊ฒ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ๋ฉ๋๋ค.
- ํ์ด์ง ์ ํ์ ์ผ๊ด์ฑ: ๋ฏธ๋ค์จ์ด์์ ์์ฒญ์ ์ ์ดํ๋ฉด, ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๋ ๋ณดํธ๋ ํ์ด์ง์ ์ ๊ทผํ๋ ค ํ ๋ ์ง์ /login ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค. ์ด๋ ์ฌ์ฉ์๊ฐ ์ค๊ฐ์ ๋ค๋ฅธ ํ์ด์ง๋ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ๋ณผ ํ์ ์์ด ์ผ๊ด๋ UX ํ๋ฆ์ ์ ์งํ๊ฒ ํฉ๋๋ค.
- ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ ์ ๊ณต: ํด๋ผ์ด์ธํธ ์ธก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์์๋ ํ์ด์ง๊ฐ ๋ก๋๋ ์ดํ์์ผ ์ ๊ทผ ๋ถ๊ฐ ๋ฉ์์ง๋ฅผ ๋ณผ ์ ์๋ ๋ฐ๋ฉด, ๋ฏธ๋ค์จ์ด๋ฅผ ํตํด ์ฆ์ ๋ฆฌ๋๋ ์ ํ๋ฉด ์ฌ์ฉ์๋ ๋น ๋ฅด๊ฒ ๋ก๊ทธ์ธ ํ์ ์ํ๋ฅผ ์ธ์งํ ์ ์์ต๋๋ค.
๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํด ์๋ฒ ์ธก์์ ํ ํฐ ๊ฒ์ฌ๋ฅผ ์งํํจ์ผ๋ก์จ, ๋ณด์์ฑ, ์ฑ๋ฅ ์ต์ ํ, ๊ทธ๋ฆฌ๊ณ ์ผ๊ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ชจ๋ ๋ณด์ฅํ ์ ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์ธก ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ํ์ด์ง๋ฅผ ์จ๊ธฐ๋ ๋ฐ ์ ํฉํ์ง ์์ผ๋ฉฐ, ๋ณดํธ๋ ์ฝํ ์ธ ์ ๋ํ ์์ ํ ์ ๊ทผ ์ ์ด๊ฐ ์ด๋ ต์ต๋๋ค. ๋ฐ๋ฉด ๋ฏธ๋ค์จ์ด๋ ์ฌ์ฉ์๊ฐ ์ฝํ ์ธ ์ ์ ๊ทผํ๊ธฐ ์ ์์ฒญ์ ์ฐจ๋จํ๋ฏ๋ก, ๋ ๊ฐ๋ ฅํ๊ณ ํจ์จ์ ์ธ ๋ฐฉ์์ผ๋ก ๋ณดํธ๋ ํ์ด์ง ์ ๊ทผ์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
๐ ์ต์ข ๊ตฌํ: ๋ฏธ๋ค์จ์ด๋ก ์ ๊ทผ ์ ์ด ์ฒ๋ฆฌ
๋ฏธ๋ค์จ์ด์์ ํน์ ๊ฒฝ๋ก์ ๋ํ ์ ๊ทผ ์ ์ด๋ฅผ ์ถ๊ฐํ์ฌ ๋ณดํธ ๊ฒฝ๋ก์ ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ ๊ฒฝ์ฐ /๋ก ๋ฆฌ๋๋ ์ ํ๋ ๊ตฌ์กฐ๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก, ์๋์ ๊ฐ์ด ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์์ ํ์ต๋๋ค.
src/
โโโapp/
โ โโโ (private)/
โ โ โโโ page.tsx // ๋ก๊ทธ์ธ๋์ง ์์ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ค ํ์ด์ง
โ โโโ (public)/
โ โโโ feed/
โ โโโ page.tsx // ๋ก๊ทธ์ธ๋ ์ฌ์ฉ์๋ง ์ ๊ทผ ๊ฐ๋ฅํ ํผ๋ ํ์ด์ง
โโโ middleware.ts // ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ์ ๊ทผ์ ์ ์ดํ๋ ๋ฏธ๋ค์จ์ด
- (public)/page.tsx: ์ฌ์ ํ ๋ก๊ทธ์ธํ์ง ์์ ์ฌ์ฉ์๋ฅผ ์ํ ๊ธฐ๋ณธ ํ์ด์ง๋ก ์ฌ์ฉํฉ๋๋ค.
- (private)/feed/page.tsx: ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ์ํ ํผ๋ ํ์ด์ง๋ก, /feed ๊ฒฝ๋ก๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. ์ด ํ์ด์ง๋ ๋ก๊ทธ์ธ๋ ์ํ์์๋ง ์ ๊ทผํ๋๋ก ์ค์ ํฉ๋๋ค.
- middleware.ts: /feed ๊ฒฝ๋ก์ ์ ๊ทผํ ๋ ๋ก๊ทธ์ธ ์ํ๋ฅผ ํ์ธํ์ฌ, ๋ก๊ทธ์ธ๋์ง ์์ ์ฌ์ฉ์๋ / ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ํ๋๋ก ์ค์ ํฉ๋๋ค.
๋ฏธ๋ค์จ์ด๋ฅผ ์ค์ ํ์ฌ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ผ /feed, /profile, /post, /search ๋ฑ ํน์ ๊ฒฝ๋ก์ ๋ํ ์ ๊ทผ์ ์ ์ดํฉ๋๋ค.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('userToken'); // ๋ก๊ทธ์ธ ์ํ ํ์ธ
const { pathname } = request.nextUrl;
// ๋ณดํธ๊ฐ ํ์ํ ๊ฒฝ๋ก๋ค์ ์ ์
const protectedPaths = ['/feed', '/profile', '/post', '/search'];
// ๋ก๊ทธ์ธ๋์ง ์์ ์ฌ์ฉ์๊ฐ ๋ณดํธ ๊ฒฝ๋ก์ ์ ๊ทผํ๋ฉด /๋ก ๋ฆฌ๋๋ ์
if (!token && protectedPaths.some((path) => pathname.startsWith(path))) {
return NextResponse.redirect(new URL('/', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/:path*'], // ๋ชจ๋ ๊ฒฝ๋ก์ ๋ํด ๋ฏธ๋ค์จ์ด ์ ์ฉ ํ ์กฐ๊ฑด๋ถ๋ก ์ ์ด
};
- ๋ก๊ทธ์ธ ์ํ ํ์ธ: userToken ์ฟ ํค๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์ํ์ธ์ง ํ์ธํฉ๋๋ค.
- ๋ณดํธ ๊ฒฝ๋ก ์กฐ๊ฑด: ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ์ ๊ทผ์ ์ ์ดํด์ผ ํ๋ ๊ฒฝ๋ก(/feed, /profile, /post, /search ๋ฑ)๋ฅผ ํ๋์ protectedPaths ๋ฐฐ์ด๋ก ๊ด๋ฆฌํ๊ณ , ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์์ ์ ๊ทผ์ ๋ง์ต๋๋ค.
- ๋ฆฌ๋๋ ์ ์ฒ๋ฆฌ: ๋ณดํธ๋ ๊ฒฝ๋ก์ ๋น๋ก๊ทธ์ธ ์ฌ์ฉ์๊ฐ ์ ๊ทผํ๋ฉด /๋ก ๋ฆฌ๋๋ ์ ํ๊ณ ๋ก๊ทธ์ธ๋ ์ฌ์ฉ์๋ง ํผ๋ ํ์ด์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
โญ๏ธ ๊ฒฐ๋ก
Next.js์์ ๊ฒฝ๋ก ๊ทธ๋ฃน(Route Groups)์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๊น๋ํ๊ฒ ์ ๋ฆฌํ๋ ๋ฐ ์ ์ฉํ์ง๋ง, URL์ ์ํฅ์ ๋ฏธ์น์ง ์์ผ๋ฏ๋ก ๋์ผํ ๊ฒฝ๋ก์์ ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ด ํ์ํ ๋ ์ถฉ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ์ฌ ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ผ ํน์ ๊ฒฝ๋ก ์ ๊ทผ์ ์ ์ดํ๋ ๋ฐฉ์์ ๋์ ํ์ต๋๋ค.
- ๊ฒฝ๋ก ๊ทธ๋ฃน์ ํน์ฑ ์ดํด: ๊ฒฝ๋ก ๊ทธ๋ฃน์ ๋๋ ํ ๋ฆฌ ์ ๋ฆฌ๋ฅผ ์ํ ๊ฒ์ด์ง, URL ์์ฒด์ ์ํฅ์ ์ฃผ์ง ์๋๋ค๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค.
- ๋ฏธ๋ค์จ์ด๋ฅผ ํ์ฉํ ์ ๊ทผ ์ ์ด: ๋ณดํธ๋ ๊ฒฝ๋ก๋ฅผ ์ ์ํ๊ณ , ๋ฏธ๋ค์จ์ด๋ฅผ ํตํด ์กฐ๊ฑด๋ถ ์ ๊ทผ ์ ์ด๋ฅผ ๊ตฌํํจ์ผ๋ก์จ ๋ ๋์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์์ต๋๋ค.
- ๋ก๊ทธ์ธ ์ฌ๋ถ์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฝํ ์ธ ์ ๊ณต: ๋ฏธ๋ค์จ์ด๋ก ์ธ์ฆ ์ํ๋ฅผ ํ์ธํ์ฌ, ์ฌ์ฉ์์ ๋ก๊ทธ์ธ ์ํ์ ๋ฐ๋ผ ๋์ ์ผ๋ก ๋ค๋ฅธ ํ์ด์ง ์ฝํ ์ธ ๋ฅผ ์ ๊ณตํ ์ ์์์ต๋๋ค.