bitForum - Next.js 15 App Router 기반 커뮤니티 프론트엔드 (https://bitforum.io)
app/ → Next.js App Router (페이지, 레이아웃, API 라우트)
├── (account)/ → 계정 관리 (프로필, 비밀번호 변경 등)
├── (auth)/ → 인증 (로그인, 회원가입, 비밀번호 찾기)
├── (forum)/ → 게시판 (게시글, 댓글, 글쓰기)
├── api/ → Route Handler (백엔드 API 프록시)
├── component/ → 공통 레이아웃 컴포넌트 (Layout, PopupModal 등)
├── support/ → 고객지원 (FAQ, 공지, 이용안내, 제휴문의)
├── news/ → 뉴스
└── docs/ → 문서 페이지
components/ui/ → shadcn/ui 컴포넌트 (dialog, accordion 등)
contexts/ → React Context Provider (Auth, Member, Config, SignalR)
hooks/ → 커스텀 훅 (useAuth, useDragScroll 등)
lib/
├── api/ → 서버 사이드 API 호출 함수 (Server Actions)
└── utils/
├── client.ts → 클라이언트 유틸 (fetchApi, cn, formatDate, throwError)
└── server.ts → 서버 유틸 (fetchJson, getAccessToken, checkPermission)
types/ → TypeScript 타입 정의 (response/, request/, forum/, account/)
constants/ → 상수 정의
middleware.ts → 인증 미들웨어 (토큰 검증, 리다이렉트)
memberID, postID (camelCase + 대문자 ID)'use client' 선언'use server' 선언 (Server Actions, lib/utils/server.ts)PopupModal.tsx, Layout.tsx)support/faq/)style.scss 파일'use client' 없으면 RSCapp/api/[도메인]/[...path]/route.ts → 백엔드
fetchJson() → 백엔드 직접 호출fetchApi<T>() — 클라이언트에서 Route Handler 호출 (lib/utils/client.ts)fetchJson<T>() — 서버에서 백엔드 직접 호출 (lib/utils/server.ts)ResultDto<T> — 모든 API 응답 래퍼 ({ success, status, message, data, errors })throwError(res) — 에러 응답 시 예외 발생cn() — Tailwind 클래스 병합 (clsx + tailwind-merge)dangerouslySetInnerHTML — 서버에서 받은 HTML 콘텐츠 렌더링(auth), (account), (forum) 으로 관련 페이지 그룹화notFound() — 데이터 없을 때 404 처리style.scss, 글로벌 globals.scsscommon.module.scss (레이아웃 그리드)components/ui/)--background, --foreground 등)SignalRProvider → AuthProvider → MemberProvider → ConfigProvider → {children}
ConfigProvider: initialConfig prop으로 서버에서 설정 전달 (React.cache)AuthProvider: 로그인 상태 관리, 토큰 갱신MemberProvider: 현재 사용자 정보SignalRProvider: WebSocket 연결 (암호화폐, 채팅)// app/api/{도메인}/[...path]/route.ts
export async function POST(request: NextRequest, { params }: { params: Promise<{ path: string[] }> }) {
const { path } = await params;
const endpoint = `/api/${path.join('/')}`;
const res: ResultDto = await fetchJson(endpoint, {
method: 'POST',
body: await request.arrayBuffer(),
headers: { 'Content-Type': request.headers.get('content-type') || '' }
});
return NextResponse.json(res);
}
# 개발 서버 (HTTPS, 포트 3000)
npm run dev
# 프로덕션 빌드
npm run build
# 프로덕션 실행
npm run start
# 린트
npm run lint