본문으로 건너뛰기

안동민 개발노트

본문 시작

전역 레이아웃 및 배포

공통 레이아웃과 내비게이션을 구성하고 로컬 및 Vercel 배포를 검증합니다.


전역 레이아웃 및 내비게이션

헤더, 푸터 등 모든 페이지에 공통으로 적용될 레이아웃을 구성하고, 내비게이션 바를 추가합니다.

app/layout.tsx (기본 생성된 layout.tsx에 추가)
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import type { ReactNode } from 'react';
import './globals.css';
import Header from '@/components/Header'; // Header 컴포넌트
import Footer from '@/components/Footer'; // Footer 컴포넌트

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: '나만의 온라인 북스토어',
  description: 'Next.js로 만든 간단한 온라인 북스토어 프로젝트',
};

export default function RootLayout({
  children,
}: {
  children: ReactNode;
}) {
  return (
    <html lang="ko">
      <body className={`${inter.className} flex flex-col min-h-screen bg-gray-100`}>
        <Header />
        <div className="grow">
          {children}
        </div>
        <Footer />
      </body>
    </html>
  );
}
components/Header.tsx
import Link from 'next/link';

export default function Header() {
  return (
    <header className="bg-white shadow-md py-4">
      <div className="container mx-auto px-4 flex justify-between items-center">
        <Link href="/" className="flex items-center space-x-2">
          <span aria-hidden="true" className="text-2xl">📚</span>
          <span className="text-2xl font-bold text-gray-800">My Bookstore</span>
        </Link>
        <nav>
          <ul className="flex space-x-6">
            <li>
              <Link href="/books" className="text-gray-600 hover:text-blue-600 transition-colors">
                모든 책
              </Link>
            </li>
            <li>
              <Link href="/cart" className="text-gray-600 hover:text-blue-600 transition-colors">
                장바구니
              </Link>
            </li>
            <li>
              <Link href="/login" className="text-gray-600 hover:text-blue-600 transition-colors">
                로그인
              </Link>
            </li>
          </ul>
        </nav>
      </div>
    </header>
  );
}
components/Footer.tsx
export default function Footer() {
  return (
    <footer className="border-t bg-white py-6 text-center text-sm text-gray-600">
      <p{new Date().getFullYear()} My Bookstore</p>
    </footer>
  );
}

배포 및 테스트

로컬에서 모든 기능이 정상적으로 작동하는지 확인한 후, Vercel에 배포합니다.

배포 전에는 기능 동작뿐 아니라 환경 변수, 데이터 연결, 빌드 결과, 배포 후 확인까지 한 번의 체크리스트로 묶어야 누락을 줄일 수 있습니다.

배포는 Deploy 버튼이 아니라 환경 변수와 핵심 흐름 검증까지 포함한다

빌드 성공 뒤에도 MongoDB, Auth.js 운영 변수, OAuth callback과 로그인부터 주문까지의 흐름을 배포 URL에서 확인한다.

단계확인할 것실패 신호조치
로컬 테스트로그인, 목록, 장바구니, 주문, 검색세션·서버 액션 오류인증과 기능 실패를 분리
빌드npm run build, 타입, lint동적 라우트/이미지/env 오류배포 전 로컬에서 해결
환경 변수MONGODB_URI, AUTH_SECRET, AUTH_GITHUB_ID, AUTH_GITHUB_SECRETDB 연결 또는 OAuth 시작 실패Production/Preview 범위 확인
OAuth callbackhttps://배포도메인/api/auth/callback/githubcallback mismatchGitHub OAuth 앱의 운영 URL 등록
배포 후실제 URL에서 로그인부터 주문까지세션·검색·주문이 로컬과 다름Vercel 로그와 네트워크 응답 확인

로컬 테스트

npm run dev

브라우저에서 http://localhost:3000에 접속하여 모든 페이지와 기능이 올바르게 동작하는지 확인합니다.

특히 장바구니 추가, 수량 변경, 삭제, 주문하기 등의 상호작용 기능을 꼼꼼히 테스트합니다.

Vercel 배포

GitHub, GitLab, 또는 Bitbucket에 프로젝트 리포지토리를 생성하고 코드를 푸시합니다.

Vercel 계정에 로그인하고 Add New Project를 통해 해당 Git 리포지토리를 임포트합니다.

Vercel이 Next.js 프로젝트임을 자동으로 감지하고 설정을 제안합니다.

환경 변수 설정: Vercel 대시보드 프로젝트 설정에서 Environment Variables 섹션으로 이동하여 MONGODB_URI, AUTH_SECRET, AUTH_GITHUB_ID, AUTH_GITHUB_SECRET을 Production 환경에 추가합니다.

데이터베이스 값은 MongoDB Atlas의 프로덕션 연결 문자열을 사용하고, AUTH_SECRET에는 충분히 긴 무작위 문자열을 사용합니다.

OAuth 운영 주소 등록: GitHub OAuth 앱에 https://배포도메인/api/auth/callback/github를 Authorization callback URL로 등록합니다.

배포: 설정 확인 후 Deploy 버튼을 클릭하면 Vercel이 자동으로 빌드하고 배포합니다.

이 단계별 가이드는 온라인 북스토어 프로젝트의 핵심 기능을 구현하는 데 필요한 주요 과정과 코드 예시를 제공합니다.

실제 프로젝트에서는 계정 모델과 역할, 사용자용 오류 UI, 관측·복구 절차를 요구사항에 맞춰 확장해야 합니다.

아래 다이어그램은 긴 코드 예시를 기능별 계약과 완료 기준으로 다시 묶어, 구현이 끝났는지 확인하는 기준을 정리합니다.

코드 예시는 기능별 계약으로 회수될 때 구현 가이드가 된다

긴 코드 블록을 따라 치는 것보다, 각 단계가 어떤 파일을 만들고 어떤 검증 신호를 남기는지 확인해야 한다.

구현 묶음파일 단위완료 판정추가할 수 있는 확장
기본 환경app, components/ui, lib/db.ts로컬 앱과 DB 연결 성공공통 레이아웃, 에러 UI
도서 기능models/Book.ts, app/books목록과 상세가 같은 모델을 사용필터, 정렬, 추천
구매 흐름auth.ts, actions/cart.ts, types/cart.tsauth() 소유권 검증과 Mongoose→CartItemDto 직렬화 통과결제, 쿠폰, 배송지
운영 준비DB·Auth.js env, OAuth callback, deploy settings배포 URL에서 로그인부터 주문까지 통과관측과 복구 절차

아래 다이어그램은 Mongoose 모델, 초기 데이터 삽입, 도서 목록, 도서 상세 페이지가 이어지는 구현 흐름을 요구사항, 구현 단위, 검토 신호가 이어지는 작업 흐름으로 정리합니다.

요구사항은 구현 단위로 내려오고, 구현 단위는 검토 신호로 닫힌다

Mongoose 모델, 초기 데이터, 목록, 상세, 장바구니, 검색, 배포는 따로 외우는 조각이 아니라 같은 MVP 흐름을 닫는 작업 단위다.

  1. 1
    데이터 준비

    .env.local, 모델, seed, book-placeholder를 한 계약으로 준비한다.

  2. 2
    읽기 화면

    목록과 상세 페이지가 Book 모델을 검증한다.

  3. 3
    구매 흐름

    auth()로 소유권을 확인하고 Mongoose 결과를 CartItemDto로 직렬화한다.

  4. 4
    운영 확인

    Auth.js env와 OAuth callback을 넣고 배포 URL의 전체 흐름을 확인한다.

요구사항구현 단위검토 신호
책을 찾는다검색 input, query, DB 조건, pagination검색어 유지와 결과 수 일치
책을 고른다목록, BookCard, 상세 페이지목록에서 상세로 이동
주문한다Auth.js userId, Server Action, CartItemDto, Order로그인·소유권·직렬화·재고 검증 통과
배포한다DB·Auth.js env, OAuth callback, Vercel운영 로그인부터 주문까지 통과