ChatGPT와 Next.js 공부

Next.js에서 AppBar, SideDrawer, Footer가 포함된 레이아웃 구현

그랜파 개발자 2025. 5. 12. 22:38

프로젝트 만들기

✅ 설치

npx create-next-app@latest my-next-blog --app --ts

 

√ Would you like to use ESLint? ... No / Yes

√ Would you like to use Tailwind CSS? ... No / Yes

√ Would you like your code inside a `src/` directory? ... No / Yes

√ Would you like to use Turbopack for `next dev`? ... No / Yes

√ Would you like to customize the import alias (`@/*` by default)? ... No / Yes

√ What import alias would you like configured? ... @/*

 

cd my-next-blog

 

npm install firebase tailwindcss@3 postcss autoprefixer

npx tailwindcss init -p

✅ tailwind.config.js

module.exports = {

  content: ["./app/**/*.{js,ts,jsx,tsx}"],

  theme: {

    extend: {},

  },

  plugins: [],

};

✅ globals.css

@tailwind base;

@tailwind components;

@tailwind utilities;

✅ 실행

npm run dev

 

예제 코드 복사

✅ 폴더 구조

/app
  ├ layout.tsx       # 전체 공통 레이아웃
  ├ page.tsx         # 홈 페이지
  └ /about
      └ page.tsx     # About 페이지
/components
  ├ AppBar.tsx
  ├ SideDrawer.tsx
  └ Footer.tsx
/styles
  └ globals.css

 

app/layout.tsx

// app/layout.tsx
import './globals.css'
import AppBar from 'app/components/AppBar'
import SideDrawer from 'app/components/SideDrawer'
import Footer from 'app/components/Footer'
import type { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'My Blog',
  description: 'A simple blog with Next.js App Router',
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body className="flex flex-col min-h-screen">
        <AppBar />
        <div className="flex flex-1">
          <SideDrawer />
          <main className="flex-1 p-4">{children}</main>
        </div>
        <Footer />
      </body>
    </html>
  )
}

 

app/page.tsx

// app/page.tsx
export default function Home() {
  return (
    <div>
      <h1 className="text-2xl font-bold mb-4">Welcome to My Blog</h1>
      <p>This is the homepage using the Next.js app directory.</p>
    </div>
  )
}

 

app/about/page.tsx

// app/about/page.tsx
export default function AboutPage() {
  return (
    <div>
      <h1 className="text-xl font-bold mb-2">About</h1>
      <p>This is the about page.</p>
    </div>
  )
}

 

components/AppBar.tsx

// components/AppBar.tsx
export default function AppBar() {
  return (
    <header className="bg-blue-600 text-white p-4">
      <h1 className="text-lg font-bold">My Blog</h1>
    </header>
  )
}

 

app/components/Footer.tsx

// app/components/Footer.tsx
export default function Footer() {
  return (
    <footer className="bg-gray-200 text-center py-3 text-sm text-gray-700">
      © 2025 My Blog
    </footer>
  )
}

 

app/components/SideDrawer.tsx

// app/components/SideDrawer.tsx
import Link from 'next/link'

export default function SideDrawer() {
  return (
    <aside className="hidden md:block w-64 bg-gray-100 p-4 border-r">
      <nav className="space-y-2">
        <Link href="/" className="block hover:text-blue-600">Home</Link>
        <Link href="/about" className="block hover:text-blue-600">About</Link>
      </nav>
    </aside>
  )
}

 

tailwind.config.js

// tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./pages/**/*.{js,ts,jsx,tsx}",      // pages 디렉토리도 포함 시킴
    "./components/**/*.{js,ts,jsx,tsx}", // components 디렉토리도 포함 시킴
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};