포트폴리오: Notion 기반 포트폴리오 & 블로그 플랫폼
포트 폴리오 내에서, 개발자가 코드 수정 없이 Notion에서 콘텐츠를 관리하면, 자동으로 최적화된 웹사이트로 변환되는 시스템입니다. 콘텐츠 관리의 편의성과 웹 성능 최적화 달성하고자 하였습니다.
1. 프로젝트 요약
- Project Overview: 기존 정적 포트폴리오 사이트의 가장 큰 문제점은 콘텐츠 업데이트의 극심한 번거로움이었습니다. 포트폴리오 프로젝트 하나를 추가하거나 블로그 글을 수정할 때마다 코드를 직접 변경하고, 빌드하고, 배포하는 비효율적인 과정을 반복해야 했습니다.
이 문제를 해결하기 위해 Notion을 Headless CMS로 활용하여, 콘텐츠 작성은 Notion에서 편리하게 하고(DX), 웹사이트는 Next.js의 SSG/ISR 기능을 통해 최적화된 성능(UX)으로 자동 빌드 및 배포되는 하이브리드 아키텍처를 구축했습니다.
- My Role: 개인 프로젝트. 초기 아이디어 구상, 기술 스택 선정, 프론트엔드 개발(Next.js, React), 성능 최적화, Vercel 배포까지 전 과정을 수행했습니다.
nextjs-notion-starter-kit템플릿을 기반으로 시작하여, 개인적인 요구사항에 맞춰 스타일링, 기능 추가, 성능 개선 등 광범위한 커스터마이징을 진행했습니다.
- Key Outcomes
- Notion API와 Next.js를 연동하여 콘텐츠 관리 편의성과 웹사이트 성능이라는 두 마리 토끼를 잡았습니다.
react-notion-x라이브러리를 활용하여 Notion의 다양한 블록 타입을 웹에서 완벽하게 렌더링하고 커스텀 스타일링을 적용했습니다.useMemo를 활용한 데이터 파싱 및 필터링 최적화로 100개 이상의 블로그 포스트도 실시간으로 필터링하는 반응성 높은 UI를 구현했습니다.

- 🌐 Live Demo:
kdh-portfolio.vercel.appkdh-portfolio.vercel.app
React와 TypeScript를 활용하여 성능과 사용성을 모두 갖춘 웹 애플리케이션을 설계하고 구현합니다. 문제 해결에 대한 깊은 이해와 팀과의 협업을 통해 프로덕트의 가치를 극대화합니다.
2. 기술 스택 및 선정 이유
- Framework:
Next.js (Pages Router),React - 선정 이유: 포트폴리오(정적 콘텐츠)는 SSG로 빌드하여 CDN에서 빠르게 제공하고, 블로그(자주 업데이트)는 ISR로 설정하여 Notion 업데이트 시 자동 재검증 및 배포되도록 하기 위해 Next.js를 선택했습니다.
- CMS & API:
Notion API,notion-client,react-notion-x - 선정 이유: (Notion) 익숙한 UI/UX를 제공하여 개발자가 아닌 사용자도 쉽게 콘텐츠를 관리할 수 있으며, 강력한 데이터베이스 기능을 통해 블로그 포스트, 포트폴리오 프로젝트 등을 구조화하여 관리하기 용이합니다. (react-notion-x) Notion의 거의 모든 블록 타입을 지원하고 커스터마이징이 용이하여 선택했습니다.
- Styling:
Styled Components - 선정 이유: 컴포넌트 기반 스타일링과 동적 테마(다크 모드 등) 구현에 용이하며, TypeScript와의 통합이 뛰어나 타입 안전성을 확보할 수 있어 선택했습니다.
- State Management:
React Hooks (useState, useMemo, useContext) - 선정 이유: 프로젝트의 상태 구조가 비교적 단순하여 Redux나 Zustand 같은 별도의 전역 상태 관리 라이브러리 없이, React 내장 훅만으로 충분히 효율적인 상태 관리가 가능하다고 판단했습니다. 특히
useMemo를 적극 활용하여 계산 비용이 높은 데이터 처리(필터링, 정렬)를 최적화했습니다.
- Deployment:
Vercel - 선정 이유: Next.js 프레임워크와의 완벽한 통합, Git 기반의 손쉬운 자동 배포(CI/CD), 글로벌 CDN 기능 지원 등 개발 및 운영 편의성을 극대화하기 위해 Vercel을 선택했습니다.
3. 아키텍처

핵심 설계
- Notion as Headless CMS: 콘텐츠의 생성 및 관리는 전적으로 Notion에서 이루어지며, 웹사이트는 Notion 데이터를 읽어와 렌더링하는 역할만 수행합니다. 이를 통해 개발자와 콘텐츠 관리자의 역할을 명확히 분리했습니다.
- UX: 100개 이상의 포스트가 있어도 빠른 속도를 유지하기 위해, 태그 필터링 및 카테고리 그룹화 로직에
useMemo를 적용하여 불필요한 재계산을 방지했습니다. 또한, 부드러운 애니메이션으로 사용자 경험을 향상시켰습니다.
4. 주요 기능
1. Notion 기반 콘텐츠 관리
- 별도의 관리자 페이지 없이 Notion에서 직접 포트폴리오 프로젝트, 블로그 게시물, 개인 정보 등을 작성하고 수정합니다. Notion의 편집 기능을 그대로 활용할 수 있습니다.
- Notion 데이터베이스의 속성(Properties) (카테고리, 태그, 상태등)을 웹사이트의 메타데이터 및 필터링 기능과 자동으로 연동합니다.
2. 웹사이트 렌더링 (SSG)
- 포트폴리오 페이지 (
/portfolio):getStaticProps를 사용한 SSG(Static Site Generation) 로 빌드 시점에 모든 콘텐츠를 미리 렌더링하여 HTML 파일로 생성합니다. CDN을 통해 즉시 제공되어 매우 빠른 초기 로딩 속도 를 보장하도록 했습니다.
3. Notion 콘텐츠 렌더링 (react-notion-x)
- Notion의 거의 모든 블록 타입(텍스트, 이미지, 토글, 콜아웃, 코드 블록, 임베드 등)을 웹에서 원본과 유사하게 렌더링합니다.
styles/notion.css파일을 통해 Notion 블록의 기본 스타일을 커스터마이징하여 웹사이트 디자인과 일관성을 유지했습니다.
4. 인터랙티브 블로그 시스템
- 실시간 필터링: 사용자가 카테고리나 태그를 클릭하면, 페이지 새로고침 없이
useMemo를 활용한 클라이언트 사이드 로직으로 즉시 관련 포스트만 필터링하여 보여줍니다.
5. 핵심 경험 및 문제 해결 과정
1. 대규모 데이터(블로그 100개+) 필터링 성능 최적화
- 문제 상황: 블로그 페이지에서 사용자가 태그를 클릭할 때마다 모든 포스트 배열을 순회하며 필터링하는 초기 로직은, 포스트 수가 증가함에 따라 UI 반응 속도를 현저히 저하시켰습니다
- 해결 과정
useMemo활용: React의useMemo훅을 사용하여 데이터 파싱, 태그 추출/정렬, 필터링, 카테고리 그룹화 등 계산 비용이 높은 작업을 메모이제이션했습니다.- Memoization Chain 설계: 각
useMemo훅이 이전 단계의 메모이제이션된 결과만을 의존하도록 데이터 처리 파이프라인을 설계하여, 불필요한 재계산을 최소화했습니다. 예를 들어, 태그 선택(selectedTags) 상태가 변경되면 필터링 로직만 재실행되고, 포스트 데이터 파싱이나 태그 목록 생성 로직은 재실행되지 않습니다. - Early Return 최적화: 선택된 태그가 없을 경우(
selectedTags.length === 0), 필터링 로직을 건너뛰고 원본 포스트 배열을 즉시 반환하도록 하여 불필요한 연산을 방지했습니다.
6. 프로젝트 성과
- 정량적 성과
- 콘텐츠 업데이트 시간: 코드 수정 및 배포 시간(수십 분) → Notion 저장 시간 (수 초).
- 정성적 성과
- 개발 경험 향상: 콘텐츠 변경을 위한 코드 작업이 완전히 사라져 개발 생산성 향상.
- 콘텐츠 관리 용이성: Notion의 직관적인 UI를 통해 누구나 쉽게 콘텐츠 업데이트 가능.
- 유지보수성: 계층 분리 및 파서 유틸리티 구현으로 코드 관리 용이성 증대.
7. 회고 및 배운 점
- 기술적 성장: Notion을 Headless CMS로 활용하는 아키텍처를 직접 설계하고 구현하면서 API 연동, 데이터 파싱, 캐싱 전략, 성능 최적화 등 백엔드와 프론트엔드를 아우르는 실전 경험을 쌓았습니다. Next.js의 SSG/ISR 동작 원리를 이해하고 Vercel 배포 파이프라인을 직접 구축하며 현대적인 웹 개발 및 배포 프로세스에 대한 이해도를 높였습니다.
react-notion-x라이브러리를 사용하면서 외부 라이브러리를 분석하고 커스터마이징하는 능력도 향상되었습니다.
- 아쉬운 점 및 개선 방향: 현재 검색 기능은 클라이언트 사이드에서 전체 포스트 목록을 필터링하는 방식으로, 포스트 수가 매우 많아질 경우 성능 한계가 있을 수 있습니다. 향후 전문 검색 엔진을 도입하고, 한국어 형태소 분석을 적용하여 검색 정확도와 성능을 개선하고 싶습니다. 또한, 독자와의 상호작용을 위해 댓글 시스템을 추가하는 것을 고려하고 있습니다.