๐Ÿš€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ์˜ค๋Š˜์˜ ํ•™์Šต

Next.js์™€ Tailwind CSS๋กœ ๋ชจ๋˜ ์›น ์•ฑ ๋งŒ๋“ค๊ธฐ

Next.js + Tailwind

๐Ÿ“‹ ์ฃผ์š” ์ž‘์—… ๋‚ด์šฉ

1. ๐Ÿงฉ ์ปดํฌ๋„ŒํŠธ ๊ตฌ์กฐํ™” ๋ฐ UI ๊ฐœ์„ 

  • ๋ชจ๋˜ํ•œ UI ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๊ตฌ์กฐํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค:
    • ModernLogo, SpaceBackground, ContentGrid, PricingSection ๋“ฑ์˜ UI ์ปดํฌ๋„ŒํŠธ
    • ๊ณ„์ ˆ๋ณ„ ํ…Œ๋งˆ๋ฅผ ์ ์šฉํ•˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ๊ฐœ์„ 
    • ๋ฐ˜์‘ํ˜• ๋ ˆ์ด์•„์›ƒ ์ ์šฉ

2. ๐Ÿ” ์ธ์ฆ ์‹œ์Šคํ…œ ๊ฐœ์„ 

  • ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๋ฆฌํŒฉํ† ๋งํ•˜๊ณ  ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค
  • JWT ํ† ํฐ ๊ด€๋ฆฌ ๊ฐœ์„  ๋ฐ ์ธ์ฆ ์ปจํ…์ŠคํŠธ(AuthContext) ์—…๋ฐ์ดํŠธ
  • ๋กœ๊ทธ์ธ ๋ชจ๋‹ฌ ์ถ”๊ฐ€ ๋ฐ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„ 

3. โš™๏ธ Next.js ๊ตฌ์กฐ ์ตœ์ ํ™”

  • _app.tsx ๋ฐ _document.js ํŒŒ์ผ ํ˜„๋Œ€ํ™”
  • ๋ผ์šฐํŒ… ๋ฐ ํŽ˜์ด์ง€ ๊ตฌ์กฐ ๊ฐœ์„ 
  • ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ๋ฅผ ํ†ตํ•œ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์„ฑ ํ–ฅ์ƒ

4. ๐ŸŽจ ์Šคํƒ€์ผ๋ง ์‹œ์Šคํ…œ ๊ฐœ์„ 

  • Tailwind CSS ์„ค์ • ์ตœ์ ํ™” ๋ฐ ๋ถˆํ•„์š”ํ•œ ์„ค์ • ์ œ๊ฑฐ
  • ์ปค์Šคํ…€ ํ…Œ๋งˆ ์‹œ์Šคํ…œ ๊ฐœ์„  ๋ฐ ๋‹คํฌ ๋ชจ๋“œ ์ง€์› ์ถ”๊ฐ€
  • ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ์— ์ผ๊ด€๋œ ์Šคํƒ€์ผ ์ ์šฉ

๐Ÿ’ก ๋ฐฐ์šด ์ 

Next.js ๊ฐœ๋ฐœ ํŒจํ„ด

"use client" // ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ์ง€์‹œ์–ด

export default function ModernLogo() {
  return (
    <div className="flex items-center space-x-2">
      {/* ๋กœ๊ณ  ๋‚ด์šฉ */}
    </div>
  )
}
  • โ€œuse clientโ€ ์ง€์‹œ์–ด๋ฅผ ํ™œ์šฉํ•œ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์™€ ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๊ตฌ๋ถ„
  • Next.js์˜ ํŽ˜์ด์ง€ ๋ผ์šฐํŒ… ์‹œ์Šคํ…œ ํ™œ์šฉ ๋ฐฉ๋ฒ•
  • ๋ ˆ์ด์•„์›ƒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•œ ์ผ๊ด€๋œ UI ์ œ๊ณต

Tailwind CSS ํ™œ์šฉ

<nav className="sticky top-0 z-20 bg-black/50 backdrop-filter backdrop-blur-md">
  {/* ๋‚ด์šฉ */}
</nav>
  • ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ๊ตฌํ˜„ ๋ฐฉ๋ฒ• (sm, md, lg ๋ธŒ๋ ˆ์ดํฌํฌ์ธํŠธ ํ™œ์šฉ)
  • ๋ฐฑ๋“œ๋กญ ๋ธ”๋Ÿฌ์™€ ๊ทธ๋ผ๋””์–ธํŠธ๋ฅผ ํ™œ์šฉํ•œ ๋ชจ๋˜ํ•œ UI ๊ตฌํ˜„
  • ๋‹คํฌ ๋ชจ๋“œ ์ง€์›์„ ์œ„ํ•œ ๋ณ€์ˆ˜ ์„ค์ •

์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„

const Layout: React.FC<LayoutProps> = ({ children, title = '์šฐ์ฃผ์™€ ์šด๋ช…์˜ ๊ธธ' }) => {
  return (
    <div className="min-h-screen flex flex-col bg-gray-900 text-white relative">
      <SpaceBackground />
      <Navbar />
      <main className="flex-grow container mx-auto px-4 sm:px-6 py-8 relative z-10">
        {children}
      </main>
      <Footer />
    </div>
  )
}
  • ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ์ปดํฌ๋„ŒํŠธ ์„ค๊ณ„ ๋ฐฉ๋ฒ•
  • SVG๋ฅผ ํ™œ์šฉํ•œ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์š”์†Œ ๊ตฌํ˜„
  • ๋ชจ๋‹ฌ ๋ฐ ๊ณตํ†ต UI ์ปดํฌ๋„ŒํŠธ ์ถ”์ƒํ™”

์ธ์ฆ ์‹œ์Šคํ…œ

const handleLogin = () => {
  if (window.Kakao) {
    // ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ตฌํ˜„
    window.location.href = KAKAO_AUTH_URL
  }
}
  • JWT ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•
  • ์†Œ์…œ ๋กœ๊ทธ์ธ(์นด์นด์˜ค) ์—ฐ๋™ ๋ฐฉ๋ฒ•
  • ์ธ์ฆ ์ƒํƒœ์— ๋”ฐ๋ฅธ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง

๐Ÿ› ๏ธ ํ•ด๊ฒฐํ•œ ๋ฌธ์ œ์ 

  1. ์ผ๊ด€์„ฑ ์—†๋Š” ์ฝ”๋“œ ์Šคํƒ€์ผ: ํ”„๋กœ์ ํŠธ ์ „๋ฐ˜์— ๊ฑธ์ณ ์ผ๊ด€๋œ ์ฝ”๋“œ ์Šคํƒ€์ผ๊ณผ ๊ตฌ์กฐ ์ ์šฉ
  2. ์ค‘๋ณต๋œ UI ๋กœ์ง: ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ ์ถ”์ถœ๋กœ ์ค‘๋ณต ์ฝ”๋“œ ์ œ๊ฑฐ
  3. ๋ชจ๋ฐ”์ผ ์ง€์› ๋ฏธํก: ๋ฐ˜์‘ํ˜• ๋””์ž์ธ ์ ์šฉ์œผ๋กœ ๋ชจ๋ฐ”์ผ ์‚ฌ์šฉ์„ฑ ๊ฐœ์„ 
  4. ๋ถˆํ•„์š”ํ•œ ์˜์กด์„ฑ: package.json ์ตœ์ ํ™” ๋ฐ ์ตœ์‹  ๋ฒ„์ „ ์ ์šฉ

๐Ÿ”ฎ ์•ž์œผ๋กœ์˜ ๊ฐœ์„  ๋ฐฉํ–ฅ

์˜์—ญ ๊ฐœ์„  ๊ณ„ํš
์„ฑ๋Šฅ ์ด๋ฏธ์ง€ ์ตœ์ ํ™” ๋ฐ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ์„ฑ๋Šฅ ๊ฐœ์„ 
์ ‘๊ทผ์„ฑ ARIA ์†์„ฑ ๋ฐ ํ‚ค๋ณด๋“œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ง€์› ํ™•๋Œ€
ํ…Œ์ŠคํŠธ ํ•ต์‹ฌ ์ปดํฌ๋„ŒํŠธ ๋ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
๊ตญ์ œํ™” ๋‹ค๊ตญ์–ด ์ง€์›์„ ์œ„ํ•œ i18n ํ†ตํ•ฉ

์˜ค๋Š˜์˜ ์ž‘์—…์„ ํ†ตํ•ด ๋ชจ๋˜ ์›น ๊ฐœ๋ฐœ์˜ ํ•ต์‹ฌ ํŒจํ„ด๊ณผ ๊ธฐ์ˆ ์„ ์ ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ปดํฌ๋„ŒํŠธ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ๊ณผ ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์˜ ์ค‘์š”์„ฑ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋А๋‚„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์ž‘์—…์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๊ธฐ๋ฐ˜ ์œ„์— ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

โ€œ์ข‹์€ ์ฝ”๋“œ๋Š” ๊ทธ ์ž์ฒด๋กœ ์ตœ๊ณ ์˜ ๋ฌธ์„œ๋‹คโ€ - ๋กœ๋ฒ„ํŠธ C. ๋งˆํ‹ด