1. 개요
Notion CMS 블로그는 Notion을 글 작성, 콘텐츠 관리 도구로 쓰고, 공개 화면은 별도 웹앱에서 렌더링하는 방식이다. 에디터 경험은 Notion에 맡기면서도 디자인, 라우팅, 검색, 배포 방식은 직접 제어할 수 있어 기존 블로그 플랫폼의 작성 편의성과 커스텀 블로그의 자유도를 함께 노릴 수 있다.
다양한 블로그 서비스 (Github Pages, Tistory, Medium, Velog)
누구나 그렇듯 대학생 시절부터 공부한 내용을 정리할 나만의 블로그를 만들고 싶다는 생각을 했었다. Github Pages, Tistory 를 써보려 했으나 아래 한계가 늘 걸림돌이었다.
| 플랫폼 | 불편했던 점 |
|---|---|
| Github Pages | 장점: 커스터마이징 쉬움 / 단점: 글 작성 과정이 번거롭고 에디터가 불편 |
| Tistory | 장점: 에디터, 기본 기능 제공 / 단점: 커스터마이징 난이도 높음, 원하는 기능 개발 어려움 |
글 쓰는 것 자체가 불편하다 보니 점점 글을 안 쓰게 되었고, 블로그 운영도 멈췄다. 몇 년이 지나 개인 스터디, 프로젝트를 진행하며 체계적으로 기록하고 다시 꺼내볼 공간이 필요하다는 걸 깨달았다.
평소 정리에 Notion 을 많이 쓰다 보니 자연스럽게 Notion 기반 블로그를 떠올렸다. 다만 단순히 Notion 페이지를 publish 하는 방식은 디자인, 기능 커스터마이징이 불가능했다. 그래서 Notion 을 CMS (Content Management System) 로 쓰고, 디자인과 기능은 직접 개발하기로 했다.
TIP
기존 블로그 플랫폼의 한계를 해결하기 위해, Notion 을 CMS 로 활용한 직접 개발 블로그를 선택했다.
2. 설계 / 구상
단순 publish 로는 카테고리, 태그 검색이나 편의 기능을 제공하기 어려웠기에, Notion 을 CMS 로 두고 기획부터 개발까지 직접 하기로 했다. 기획은 퇴근 후 틈틈이 진행해 약 1달이 걸렸다.
컴포넌트 디자인 전, 블로그 색감을 정할 때 v0.dev 로 컬러 팔레트를 만들어 친구들에게 자문을 구했다(배경색은 직접 정함).
v0.dev 로 그린 컬러 팔레트
이후 가장 작은 단위의 컴포넌트(Typography, Button 등) 부터 시작해 확장하는 구조로 디자인을 진행하고, 친구들의 피드백으로 수정을 반복했다.
NOTE
색감과 컴포넌트 단위 디자인을 먼저 잡고 확장하는 방식이 이후 개발 속도를 높이는 데 도움이 된다.
피그마로 직접 그린 블로그 컴포넌트 디자인
컴포넌트를 기반으로 만든 페이지 디자인
3. 개발 / 구현
이 프로젝트는 Figma MCP + Github Copilot 을 사용한 Vibe Coding 방식으로 진행했다.
Figma 와 Github Copilot
Figma 로 디자인한 컴포넌트 URL 만 넣으면(사전 설정 필요) Github Copilot 이 컴포넌트 코드, Storybook, 테스트 코드를 작성해 주었다.
├── PostRow
│ ├── PostRow.stories.tsx
│ ├── PostRow.test.tsx
│ ├── PostRow.tsx
│ └── index.tsx
└── TagList
├── TagList.stories.tsx
├── TagList.test.tsx
├── TagList.tsx
└── index.tsx다만 FE 경험이 부족했던 나에게는 Vibe Coding 중에도 고민이 끊이지 않았다.
"Props 설계는 지금 할까 나중에 할까? 디자인 요소부터 개발할까? 다크 모드는 언제 만들까? Notion 데이터 로직을 먼저 구현할까?"
일단 부딪혀가며 수많은 시행착오와 리팩토링을 거듭했다. Vibe Coding 특성상 AI 가 작성한 코드가 의도와 다르게 동작하는 경우가 있어, 품질 유지를 위해 CI 환경에 공을 들였다.
3.1. Storybook & 테스트 코드 의무화
copilot-instructions.md 에 "컴포넌트 구현 시 반드시 Storybook 과 테스트 코드를 작성할 것"을 명시하고, codecov.yml 로 테스트 커버리지 80% 이상을 목표로 했다.
coverage 리포트 예시
3.2. Github Actions 기반 자동 테스트
PR 을 올리면 Github Actions 가 자동으로 테스트, 빌드를 실행하도록 설정했다. 빌드 + 테스트 + 정적 분석이 모두 통과해야만 main 에 merge 되도록 해, 깨진 코드가 병합되는 최악의 상황을 막았다.
Github Checks 항목
3.3. Dependabot 을 이용한 패키지 관리
dependabot.yml 에 업데이트 규칙을 정의하고, auto-merge 는 별도 설정(GitHub Actions 워크플로 등)으로 구성해 의존성을 주기적으로 갱신했다. 덕분에 오래된 라이브러리 방치를 막고 보안 패치도 빠르게 적용할 수 있었다.
dependabot + auto-merge 로 dev 패키지 자동 업데이트
4. 배포
배포 방식은 오래 고민한 부분이다. 처음엔 자체 서버 배포를 생각했지만, 블로그는 정적(static) 빌드만으로 충분해 굳이 서버가 필요 없었다. 그래서 Github Pages 를 선택해, Notion 글을 빌드 시점에 정적으로 변환한 결과물을 배포하는 방식으로 갔다.
그런데 빌드를 실행할 때마다 Notion 데이터를 가져오는 부분에서 timeout 이 발생했다. 원인을 못 찾다가 react-notion-x의 Notion page fetch 동작과 관련 사례를 찾아보니, collection/database가 있는 페이지에서 fetch가 멈출 수 있는 맥락이 있었다.
NOTE
(2025.09.29 기준) react-notion-x 7.6 버전에서 해당 fetch 문제가 해결되어 더 이상 발생하지 않는다.
제안된 대로 react-notion-x 를 특정 버전으로 다운그레이드하니 빌드가 정상 완료됐고, 마침내 자체 개발한 Notion CMS 기반 블로그를 배포할 수 있었다.
WARNING
정적 빌드 배포를 선택할 때는, 사용하는 라이브러리의 빌드 타임 동작까지 미리 검증해두는 것이 중요하다.
5. 마무리 / 회고
처음엔 2달이면 끝날 줄 알았지만, 기획이 길어지고 개인 사정이 겹쳐 총 4달이 걸렸다. 그래도 퇴근 후 틈틈이 완성해 배포까지 마쳐 뿌듯했다. 올해 목표였던 연간 사이드 프로젝트 2개 중 하나를 마무리했고, 첫 React 기반 FE 프로젝트에서 더 나은 프로세스, 구조를 고민할 수 있었다.
아직 남은 기능도 있다(언젠가 구현 예정).
- About 페이지
- ToC (Table of Contents)
- Fuzzy Search
마지막으로 기획, 디자인, 기능 하나하나에 피드백을 아끼지 않은 친구들에게 고맙다는 말을 전하고 싶다.
TIP
Vibe Coding 은 생산성을 높여주지만, 설계 고민과 CI 구축은 여전히 개발자의 몫이었다. 다음 프로젝트에서는 초반 설계에 더 많은 시간을 투자할 예정이다.