React + TypeScript 기반 포트폴리오 사이트
- 초기: 정적 로딩 i18n
- 이후 필요 시: 동적 로딩 전환 가능
- 다크/라이트 테마, EN/KR 다국어, SEO 기본 대비
- 앱: React, TypeScript, Vite, React Router
- 스타일: Tailwind CSS(+ CSS Variables), 선택: shadcn/ui, lucide-react
- i18n: react-i18next (정적 리소스 로딩, 동적 전환 준비)
- 품질: ESLint, Prettier, (선택) Vitest + Testing Library
- 배포: Vercel / Netlify / GitHub Pages 중 택1
- Feature-based 구조: 페이지는 라우팅 단위, 기능(feature)별로 UI/Hooks/Services를 모듈화
- Content-first: 텍스트/프로젝트 데이터는
/content에서 관리 (후일 CMS/API로 교체 용이) - 전역 상태 최소화: 테마/언어 등 전역 컨텍스트만 유지, 데이터는 페이지 단위 hooks로
src/
├─ app/ # 전역 레이어(비즈니스 로직 금지)
│ ├─ layout/
│ │ ├─ RootLayout.tsx # 공통 레이아웃(헤더/푸터/컨테이너)
│ │ └─ Header.tsx # 테마/언어 토글 버튼 위치 추천
│ ├─ routes/
│ │ └─ index.tsx # createBrowserRouter 정의
│ ├─ providers/
│ │ ├─ AppProviders.tsx # 모든 Provider 합쳐 감싸기
│ │ ├─ ThemeProvider.tsx # data-theme 관리(useTheme 훅 포함)
│ │ └─ I18nProvider.tsx # react-i18next 세팅(useLocale 훅)
│ └─ config/
│ ├─ site.ts # 사이트명, 기본 메타/OG
│ └─ env.ts # 공개 env 파싱(예: VITE_* 검증)
│
├─ pages/ # 라우트 단위(얇게 유지)
│ ├─ home/
│ │ └─ index.tsx
│ ├─ projects/
│ │ └─ index.tsx
│ ├─ project-detail/
│ │ └─ index.tsx # /projects/:slug
│ └─ about/
│ └─ index.tsx
│
├─ features/ # 도메인 모듈(응집+교체 용이)
│ ├─ projects/
│ │ ├─ components/
│ │ │ ├─ ProjectCard.tsx
│ │ │ └─ ProjectList.tsx
│ │ ├─ hooks/
│ │ │ ├─ useProjects.ts
│ │ │ └─ useProjectBySlug.ts
│ │ ├─ services/ # 데이터 접근 아답터 계층
│ │ │ ├─ content.adapter.ts # 현재: content/* 읽기
│ │ │ └─ api.adapter.ts # 추후: REST/GraphQL 교체 포인트
│ │ └─ types/
│ │ └─ project.ts # Project/Tag 등 타입
│ └─ profile/
│ ├─ components/
│ ├─ hooks/
│ └─ types/
│
├─ shared/ # 진짜 공용(디자인/유틸/훅)
│ ├─ ui/
│ │ ├─ Button.tsx
│ │ ├─ Card.tsx
│ │ ├─ Tag.tsx
│ │ └─ Icon.tsx
│ ├─ styles/
│ │ ├─ tokens.css # CSS 변수(라이트/다크 토큰)
│ │ └─ tailwind.css # @tailwind base/components/utilities
│ ├─ hooks/
│ │ ├─ useMediaQuery.ts
│ │ └─ useMounted.ts
│ ├─ lib/
│ │ ├─ clsx.ts # 클래스 머지
│ │ └─ fetcher.ts # fetch 래퍼(추후 API 사용 시)
│ └─ types/
│ └─ index.ts
│
├─ content/ # 파일 기반 소스(로컬 CMS)
│ ├─ i18n/
│ │ ├─ en/ # 네임스페이스별 JSON
│ │ │ ├─ common.json
│ │ │ ├─ home.json
│ │ │ └─ projects.json
│ │ └─ ko/
│ │ ├─ common.json
│ │ ├─ home.json
│ │ └─ projects.json
│ └─ projects/
│ ├─ list.json # 목록 카드 데이터(요약)
│ ├─ aiku.mdx # 상세 페이지용 MDX(선호 시)
│ └─ profile.json # 본인 소개/스킬/링크 등
│
├─ assets/ # 정적 리소스(이미지/아이콘)
│ ├─ images/
│ └─ icons/
│
├─ main.tsx # Router + Providers 부트스트랩
├─ env.d.ts
└─ index.css # shared/styles/tailwind.css import/content/projects/list.json: 카드 리스트용 요약 데이터/content/projects/<slug>.mdx: 상세 페이지(문서처럼 관리하고 싶을 때)/content/profile.json: 이름, 역할, 소셜, 스킬/툴 목록/content/i18n/{en,ko}/{namespace}.json: 문구 리소스(정적 로딩)
선택: 상세도 JSON으로 두고 싶으면
detail.json+ 템플릿으로 랜더링 가능
MDX를 쓰면 하이라이트/코드/이미지 삽입이 유연함
/→ Home/about→ About/projects→ Projects (필터/검색 optional)/projects/:slug→ Project Detail- (선택)
/contact
-
현재: 정적 로딩(리소스 import)
- 장점: 설정 단순, 초기 불러오기 예측 가능
- 폴더:
content/i18n/en|ko/{common,home,...}.json
-
전환 대비: 동적 로딩으로 변경 시
loadPath: "/locales/{{lng}}/{{ns}}.json"형태로 경로 매핑- 같은 폴더 구조를
public/locales로 노출하거나 간단한 API/CMS로 교체 - 코드에서는
resources제거 + Backend 플러그인 추가만 하면 됨
- Tailwind + CSS Variables
:root에 색/간격/폰트 토큰 정의,.dark에서 오버라이드- 다크/라이트 전환: 루트에 class 토글(토글 버튼은 UI에서 구현)
- 전역: 테마/언어만 Context Provider로
- 데이터: 페이지/feature 레벨 hooks에서 파일 로딩 (→ 추후 API 교체 시 services만 수정)
- SEO: 페이지별 메타 title/description/OG 준비 (react-helmet-async 등)
- a11y: 키보드 포커스, 대비, ARIA 라벨 기본 점검
- 이미지: alt 텍스트, 썸네일 규격(예: 1200×630) 통일
- 초기 설정: Vite + TS, Tailwind, ESLint/Prettier
- 전역 Provider: Theme / i18n / SEO Provider 세팅
- 레이아웃: Header(언어/테마 토글 자리), Sidebar, Footer
- 공통 UI: Button, Card, Tag, SectionHeader, ExternalLink
- 콘텐츠 연동:
/content의 JSON/MDX를 services/hooks로 읽어 표시 - 페이지 구성: Home → About → Projects → Project Detail
- 애니메이션(선택): Framer Motion으로 섹션/카드 등장
- 품질 체크: ESLint, 포맷팅, a11y 점검
- 배포: Vercel/Netlify 연결, 프리뷰 URL 확인
- Vercel: Git 연동/미리보기 간편
- Netlify: 폼/리다이렉트 편의성
- GitHub Pages: 가벼운 정적 호스팅 (React Router는 SPA 폴백 설정 필요)
- 콘텐츠 변경:
/content내 파일 수정 → 앱 즉시 반영 (정적 로딩은 재빌드 필요) - 번역 추가:
content/i18n/<lng>/<ns>.json에 키 추가 → 없는 키는 fallbackLng로 표시 - 프로젝트 추가:
list.json에 카드 추가 + 필요 시<slug>.mdx작성
- Layout 관련 Header / Navbar 상단에 이름, 메뉴(Home, About, Projects 등), 다크모드 토글 같은 걸 넣는 공통 헤더. Footer 연락처, 소셜 링크, 저작권 표기 등을 담을 하단 컴포넌트. Container / Section Wrapper 각 페이지 섹션(About me, Projects 등)을 동일한 패딩·정렬로 감싸주는 박스.
- Typography / Text Block Title / Subtitle 컴포넌트 "Hello.", "About me." 같은 큰 제목을 일관되게 스타일링. Paragraph / Description 여러 설명 문단을 꾸준한 폰트 크기와 간격으로 보여줄 수 있는 블록.
- 카드형 UI Skill Card / Tool Card Skills & Tools 부분처럼 아이콘 + 텍스트 조합. Project Card 썸네일(이미지) + 프로젝트명 + 버튼(Detail 보기). Experience / Education Card 좌측에 항목 이름(학교, 자격증 등), 우측에 내용이 오는 카드.
- 리스트/정보 블록 Timeline / List Item Education, Certifications, Honors & Awards를 같은 형식으로 표시하는 컴포넌트. Project Detail Section Role, Used Skills, About 같은 항목을 묶어서 보여주는 섹션.
- Media 관련 Avatar / Profile Image 컴포넌트 현재 상단에 있는 Memoji 같은 걸 재사용 가능하게. Image Card 프로젝트 이미지, 로고 등을 일정한 스타일로 감싸는 UI.
- Form / Interaction Contact Form / Input Field "Get in touch" 영역에서 쓰일 Input, Textarea, Submit 버튼. Link / ExternalLink 아이콘 포함된 외부 링크 버튼 (GitHub, LinkedIn).