이 문서는 이 저장소 루트(./)에서 작업하는 사람/에이전트를 위한 실행 가이드입니다.
- 스택: Next.js App Router + TypeScript + Tailwind CSS + Zustand
- 런타임: React 19, Next 15
- 데이터: 외부 백엔드 API(
https://api.yonghun.me) + Supabase Storage - 주요 도메인:
- 포트폴리오/소개 페이지
- 블로그 목록/상세/작성 페이지
- SEO(메타데이터, sitemap, robots)
src/app: 라우트 및 페이지(App Router)src/app/posts: 블로그 목록/상세/작성 UIsrc/components: 공통 UI, provider, 레이아웃 컴포넌트src/lib/api: API 호출 유틸 및 도메인 API 함수src/lib/supabase: Supabase 클라이언트src/data: 정적 데이터src/store: Zustand 스토어
현재 코드 기준으로 아래 키를 사용합니다.
NEXT_PUBLIC_API_BASE_URLNEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_GOOGLE_ANALYTICS
주의:
NEXT_PUBLIC_*값은 클라이언트에 노출됩니다. 비밀값(secret)은 절대 넣지 않습니다.- API 기본값 fallback은
http://localhost:8080입니다(src/lib/api/apiClient.tsx).
- 개발 서버:
npm run dev - 빌드:
npm run build - 프로덕션 실행:
npm run start - 린트:
npm run lint
작업 완료 전 최소 검증:
npm run lint- 변경한 라우트 수동 확인(특히
posts,posts/[id],posts/add) - SEO 변경 시 메타데이터/OG/canonical 값 확인
최근 커밋 로그를 보면 feat/fix/docs/refactor/style 타입은 잘 사용되지만, 대소문자(Feat, Fix, Docs)가 섞여 있습니다.
앞으로는 아래 규칙으로 통일합니다.
형식:
<type>: <subject>
규칙:
type은 반드시 소문자subject는 한국어/영어 모두 가능, 짧고 구체적으로 작성- 마침표(
.) 생략 - 한 커밋에는 하나의 목적만 담기
허용 타입:
feat: 기능 추가/확장fix: 버그 수정refactor: 동작 변화 없는 구조 개선style: UI 스타일 변경(로직 영향 없음)docs: 문서 수정chore: 빌드/설정/의존성/기타 유지보수
좋은 예시:
feat: posts 페이지 성능 및 SEO 최적화fix: posts 목록 빈 상태 처리 오류 수정refactor: blog API 응답 타입 분리docs: README 배포 섹션 업데이트
피해야 할 예시:
Feat: 수정(타입 대문자 + 의미 불명확)fix: 이것저것 수정(범위 과다)
- 브랜치명:
feature/*,fix/*,refactor/*,docs/* - PR 제목도 커밋 규칙과 동일한 톤 권장
- PR 본문에 반드시 포함:
- 변경 목적
- 주요 변경 파일
- 사용자 영향(화면/API/SEO)
- 테스트/검증 결과
- TypeScript
strict를 깨는any남발 금지 - 기존 import alias(
@/*) 우선 사용 - API 레이어(
src/lib/api/*)에서 타입 우선 정의 후 페이지에 전달 - 네트워크 요청 실패 경로를 고려하고, 사용자 노출 메시지/상태를 처리
- 불필요한 클라이언트 컴포넌트(
"use client") 증가 지양 - 이미지/콘텐츠 변경 시 성능(LCP), 접근성(alt), SEO 메타데이터를 함께 확인
next.config.ts의/api/:path*rewrites는 백엔드 연동 핵심 경로이므로 함부로 변경하지 않습니다.src/lib/api/blog.tsx의revalidate(ISR) 정책 변경 시 캐시 전략을 PR에 명시합니다.posts/add인증 흐름(AuthForm,Auth) 변경 시 Guest/Admin 분기 동작을 반드시 수동 검증합니다.- Supabase 업로드 로직 변경 시 public URL, placeholder, blur 데이터 동작까지 함께 확인합니다.
다크 글래스모피즘 + 인터랙티브 이펙트 기반의 크리에이티브 개발자 포트폴리오 스타일.
- 배경색:
#0a0a0a(거의 검정) - 텍스트: 흰색/회색 계열 (
#ededed) - 배경 레이어:
NoiseBackground(노이즈 텍스처) +ParticleCanvas(파티클)
- 기본 카드/컨테이너:
backdrop-blur-lg bg-white/10 border border-white/10 shadow-2xl rounded-2xl GlassBox컴포넌트가 카드·버튼·레이아웃의 기본 단위 (src/components/ui/GlassBox.tsx)withActionprop 시 호버 시 빛이 스치는 shimmer 애니메이션 내장- 새 UI 요소 추가 시
GlassBox를 우선 활용
- 메인 강조색:
blue-500(text-blue-500) - 서브/태그:
indigo-200(text-indigo-200) - 링크 기본색:
#7c86ff, 호버 시 흰색 + 네온 글로우 - 에러/경고:
red-300(text-red-300)
- 마우스 reveal 효과:
MaskContainer(홈 메인) - 마우스 추적 빛:
Spotlight - 글자 호버 글로우:
hover:drop-shadow-glow(0 0 5px #fff, 0 0 10px #00ffff) - 페이지/요소 전환: Framer Motion (
motion/react) 사용 - 호버 흔들림:
hover:animate-shake-rotate
- 본문: Inter, Noto Sans KR (
--font-body) - 홈 메인 카피: 나눔펜 (
--font-nanum, 손글씨 느낌) - 모노스페이스:
--font-mono(코드 블록 등)
- 새 컴포넌트 추가 시 기존 글래스모피즘 패턴(
bg-white/10 border-white/10)을 유지 - 밝은 배경/라이트 테마 요소는 사이트 컨셉과 맞지 않으므로 지양
- 애니메이션은 Framer Motion 또는 Tailwind 커스텀 애니메이션(
globals.css) 사용
- 코드가 린트 오류 없이 통과한다.
- 변경 범위의 핵심 페이지가 의도대로 동작한다.
- 커밋 메시지가 소문자 타입 규칙을 지킨다.
- 문서/타입/코드가 서로 모순되지 않는다.