๐Ÿ›ค๏ธ Next.js Pages Router vs App Router โ€” ์ง์ ‘ ์จ๋ณธ ๊ฐœ๋ฐœ์ž ํ›„๊ธฐ!

๊น€๋™ํ˜ยท2025๋…„ 5์›” 21์ผ
8
post-thumbnail

๐Ÿ›ค๏ธ Next.js Pages Router vs App Router โ€” ์ง์ ‘ ์จ๋ณธ ๊ฐœ๋ฐœ์ž ํ›„๊ธฐ!

โ€œ์ด๊ฑด ๋‹จ์ˆœํ•œ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์ฐจ์ด๊ฐ€ ์•„๋‹ˆ์—ˆ์Šต๋‹ˆ๋‹คโ€ฆ ๋ฌธ๋ช… ์ „ํ™˜์ด์—ˆ์ฃ !โ€ โ€“ ์ดˆ๋ณด์ž๋ฅผ ์œ„ํ•œ ๋น„๊ต & ์‚ฌ์šฉ๊ธฐ


๐Ÿ“Œ ๋“ค์–ด๊ฐ€๊ธฐ ์ „์—: "๋ผ์šฐํŒ…"์ด ๋ญ์˜ˆ์š”?

**๋ผ์šฐํŒ…(Routing)**์€ ๋ง ๊ทธ๋Œ€๋กœ โ€œ๊ธธ ์ฐพ๊ธฐโ€์ž…๋‹ˆ๋‹ค.

์›น์—์„œ ์ฃผ์†Œ์ฐฝ์— https://example.com/about์„ ์ž…๋ ฅํ•˜๋ฉด,
์–ด๋–ป๊ฒŒ React ์•ฑ์€ ์ž๋™์œผ๋กœ /about์— ํ•ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ค„๊นŒ์š”?

๐Ÿ‘‰ ๋ฐ”๋กœ ๋ผ์šฐํ„ฐ๊ฐ€ ๊ทธ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค!


๐Ÿ“˜ ์šฉ์–ด ์„ค๋ช…: ๋ผ์šฐํ„ฐ(Router)

URL์— ๋”ฐ๋ผ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ค„์ง€ ์ •ํ•ด์ฃผ๋Š” ์‹œ์Šคํ…œ.
Next.js์—์„œ๋Š” ํด๋”์™€ ํŒŒ์ผ ๊ตฌ์กฐ๋งŒ์œผ๋กœ ์ด๊ฑธ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”!


๐Ÿง“ Pages Router: ์˜›๋‚  Next.js์˜ ํ‘œ์ค€ ๋ฐฉ์‹

๐Ÿ“ ๊ตฌ์กฐ๋Š” ์ •๋ง ๊ฐ„๋‹จํ•ด์š”:

pages/
โ”œโ”€โ”€ index.tsx        // /
โ”œโ”€โ”€ about.tsx        // /about
โ””โ”€โ”€ blog/
    โ””โ”€โ”€ [slug].tsx   // /blog/:slug

๐Ÿ‘ถ ์ดˆ๋ณด์ž ์ฝ”๋ฉ˜ํŠธ:

๋”ฑ ๋ด๋„ โ€œ์ด ํŒŒ์ผ์ด ์–ด๋–ค ์ฃผ์†Œ๋กœ ์—ฐ๊ฒฐ๋ ์ง€โ€ ๋ฐ”๋กœ ๋ณด์ด์ฃ !
๊ทธ๋ž˜์„œ ์ž…๋ฌธ์ž๋“ค์ด ์ฒ˜์Œ Next.js๋ฅผ ๋ฐฐ์šธ ๋•Œ ๋ถ€๋‹ด์ด ์ ์–ด์š”.


โœ… ์žฅ์ 

  • ์ง„์ž… ์žฅ๋ฒฝ์ด ๋‚ฎ์Œ
  • ๋น ๋ฅด๊ฒŒ MVP(ํ”„๋กœํ† ํƒ€์ž…) ๋งŒ๋“ค ๋•Œ ์ตœ๊ณ 
  • SSR/SSG ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

โŒ ๋‹จ์ 

  • ๋ ˆ์ด์•„์›ƒ์„ ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ณต๋ถ™ํ•˜๊ฒŒ ๋จ
  • error, loading ์ฒ˜๋ฆฌ๊ฐ€ _app.tsx, _error.tsx์— ๋ชฐ๋ฆผ
  • ์ค‘์ฒฉ ๋ผ์šฐํŒ…์ด ๋ณต์žกํ•จ


๐Ÿš€ App Router: ์ตœ์‹  Next.js์˜ ์ •์„

Next.js 13๋ถ€ํ„ฐ ๋„์ž…๋œ app ๋””๋ ‰ํ† ๋ฆฌ ๊ธฐ๋ฐ˜์˜ ๋ผ์šฐํ„ฐ์ž…๋‹ˆ๋‹ค.

app/
โ”œโ”€โ”€ layout.tsx              // ์ „์ฒด ๋ ˆ์ด์•„์›ƒ
โ”œโ”€โ”€ page.tsx                // /
โ”œโ”€โ”€ about/
โ”‚   โ””โ”€โ”€ page.tsx            // /about
โ”œโ”€โ”€ blog/
โ”‚   โ””โ”€โ”€ [slug]/
โ”‚       โ”œโ”€โ”€ page.tsx        // /blog/:slug
โ”‚       โ”œโ”€โ”€ loading.tsx     // ๋กœ๋”ฉ UI
โ”‚       โ””โ”€โ”€ error.tsx       // ์—๋Ÿฌ UI

๐Ÿ‘ถ ์ดˆ๋ณด์ž ์ฝ”๋ฉ˜ํŠธ:

์ฒ˜์Œ ๋ณด๋ฉด ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์‹ค์ œ๋กœ๋Š” ์—ญํ• ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋‚˜๋‰˜์–ด ์žˆ์–ด์„œ
์œ ์ง€๋ณด์ˆ˜๋‚˜ ํ™•์žฅ์„ฑ ๋ฉด์—์„œ๋Š” ํ›จ์”ฌ ํŽธํ•ด์š”!


๐Ÿ“˜ ์šฉ์–ด ์„ค๋ช…: layout.tsx

ํ•ด๋‹น ํด๋”์˜ ๋ชจ๋“  ํ•˜์œ„ ํŽ˜์ด์ง€์— ๊ณตํ†ต์œผ๋กœ ์ ์šฉ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ.
์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์ด๋“œ๋ฐ”, ํ—ค๋”, ๊ณตํ†ต ๋„ค๋น„๊ฒŒ์ด์…˜์„ ์ด๊ณณ์— ๋‘ฌ์š”.


โœ… ์žฅ์ 

  • ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ  ๋ชจ๋“ˆํ™”๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์Œ
  • ํŽ˜์ด์ง€๋ณ„ ๋กœ๋”ฉ/์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ(RSC) ๊ธฐ๋ณธ ์ง€์› โ†’ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ€๋ฒผ์›Œ์ง!

โŒ ๋‹จ์ 

  • 'use client' ์„ ์–ธ์ด ๋‚ฏ์„ค ์ˆ˜ ์žˆ์Œ
  • ๊ธฐ์กด ํ”„๋กœ์ ํŠธ์—์„œ ์ „ํ™˜ํ•˜๋ ค๋ฉด ํ•™์Šต์ด ํ•„์š”


๐Ÿ” ์ฝ”๋“œ๋กœ ๋น„๊ตํ•ด๋ณด์ž

๐Ÿ‘ด Pages Router

// pages/blog/[slug].tsx
export async function getServerSideProps(context) {
  const post = await fetchPost(context.params.slug);
  return { props: { post } };
}

export default function PostPage({ post }) {
  return <div>{post.title}</div>;
}

๐Ÿง’ App Router

// app/blog/[slug]/page.tsx
export default async function PostPage({ params }) {
  const post = await fetchPost(params.slug);
  return <div>{post.title}</div>;
}

๐Ÿ“˜ ์šฉ์–ด ์„ค๋ช…: params

URL์—์„œ [slug]์— ๋“ค์–ด๊ฐ€๋Š” ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฐ์ฒด์˜ˆ์š”.
์˜ˆ: /blog/hello-world โ†’ params.slug === "hello-world"


๐Ÿœ๐Ÿฑ ๋น„์œ ๋กœ ์ดํ•ดํ•˜๋Š” ๋‘ ๋ผ์šฐํ„ฐ

๋น„์œ Pages RouterApp Router
๐Ÿœ ๋ผ๋ฉด๋ชจ๋“  ๊ฑธ ํ•œ ํŒŒ์ผ์— ์„ž์Œ โ†’ ๋น ๋ฅด์ง€๋งŒ ๋ณต์žกํ•จโŒ
๐Ÿฑ ๋„์‹œ๋ฝ๋ฐ˜์ฐฌ๋ณ„๋กœ ์นธ ๋‚˜๋ˆ” โ†’ ๊น”๋”ํ•˜๊ณ  ํ™•์žฅ์„ฑ ์ข‹์Œโœ…

๐Ÿ‘ถ ์ดˆ๋ณด์ž ํŒ:

ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง€๋ฉด ๊ฒฐ๊ตญ ๋„์‹œ๋ฝ ๊ตฌ์กฐ๊ฐ€ ํ›จ์”ฌ ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์›Œ์š”.
ํŒ€ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” App Router๊ฐ€ ํ›จ์”ฌ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค!


๐Ÿ’ฌ ๋‚ด๊ฐ€ ์ง์ ‘ ์จ๋ณธ ํ›„๊ธฐ

  • ์ฒ˜์Œ์—” pages/ ๊ตฌ์กฐ๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ ๋„ˆ๋ฌด ๋ณต์žกํ•ด์ ธ์„œ App Router๋กœ ์ „ํ™˜
  • layout.tsx ํ•˜๋‚˜๋กœ ๋ ˆ์ด์•„์›ƒ ์žฌ์‚ฌ์šฉ์ด ํŽธํ–ˆ๊ณ 
  • Supabase์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ์—ฐ๋™ํ•ด์„œ ์„ฑ๋Šฅ๋„ ์ข‹์•„์กŒ์Œ
  • loading.tsx, error.tsx ๊ฐ™์€ ๋ถ„๋ฆฌ ๊ตฌ์กฐ ๋•๋ถ„์— ๋””์ž์ด๋„ˆ ํ˜‘์—…๋„ ์‰ฌ์›Œ์กŒ์Œ

๐Ÿ“˜ ์šฉ์–ด ์„ค๋ช…: Supabase

Firebase ๋Œ€์ฒด ์„œ๋น„์Šค. DB๋ฅผ ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.



๐Ÿ› ๏ธ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒ (pages โ†’ app)

  1. pages/์—์„œ ์“ฐ๋˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ app/์œผ๋กœ ๋ณต์‚ฌ
  2. ์„œ๋ฒ„์—์„œ fetch ํ•˜๋Š” ๋ถ€๋ถ„์€ page.tsx์—์„œ ์ฒ˜๋ฆฌ
  3. ๊ณตํ†ต UI๋Š” layout.tsx๋กœ ๋ถ„๋ฆฌ
  4. ํด๋ผ์ด์–ธํŠธ๋งŒ ์“ฐ๋Š” ์ปดํฌ๋„ŒํŠธ์—๋Š” 'use client' ์„ ์–ธ
  5. ์ ์ง„์ ์œผ๋กœ ํ•˜๋‚˜์”ฉ ์ „ํ™˜ํ•˜๋ฉด ๋จ (ํ˜ผํ•ฉ ์‚ฌ์šฉ ๊ฐ€๋Šฅ!)

๐ŸŽฏ ์ •๋ฆฌ: ์–ด๋–ค ๋ผ์šฐํ„ฐ๋ฅผ ์จ์•ผ ํ• ๊นŒ?

์ƒํ™ฉ์ถ”์ฒœ ๋ฐฉ์‹
๋น ๋ฅด๊ฒŒ MVP ๋งŒ๋“ค๊ธฐPages Router โœ…
์ •์  ์‚ฌ์ดํŠธ, ๋ธ”๋กœ๊ทธPages Router โœ…
๋ฐ์ดํ„ฐ ํŒจ์นญ ๋งŽ์€ SaaS ์„œ๋น„์ŠคApp Router โœ…
ํ˜‘์—… ๋งŽ๊ณ  ๊ตฌ์กฐ๊ฐ€ ํฐ ํ”„๋กœ์ ํŠธApp Router โœ…
SSR + RSC + ์ค‘์ฒฉ ๋ผ์šฐํŒ… ์›ํ•˜๋Š” ๊ฒฝ์šฐApp Router โœ…

profile
๐Ÿฑ ๋„์ฟ„์—์„œ ํ™œ๋™ ์ค‘์ธ ์›น ๊ฐœ๋ฐœ์ž ๐Ÿ‡ฏ๐Ÿ‡ต๐Ÿ’ป ๐Ÿง‘โ€๐Ÿ’ป ์ตœ๊ทผ์—๋Š” ์š”์ฆ˜IT์—์„œ ์ž‘๊ฐ€๋กœ๋„ ํ™œ๋™ ์ค‘์ž…๋‹ˆ๋‹ค! ๐Ÿ“ ์š”์ฆ˜IT ๊ธ€ ๋ชจ์Œ: https://yozm.wishket.com/magazine/@donghyuk65/

0๊ฐœ์˜ ๋Œ“๊ธ€