블로그_05_BlockNote 에디터 도입 및 커스터마이징
웹 에디터 기능 구현의 여정
웹 에디터 구현 성공
- 목차와 아웃라인 디자인 통일 등 아직 손볼 건 보이지만 오늘은 일단 여기까지


왜 웹 에디터가 필요했는가?
현재 블로그는 로컬에서 마크다운 파일을 수정하고 Git으로 푸시해 콘텐츠를 업데이트한다.
문제는 단순한 오탈자 수정이라도 웹에 반영하려면 커밋하고 푸시해야 한다는 점이었다.
의미 없는 커밋 개수가 늘어나는 것도 싫었고 번거롭다는 생각이 들어서
웹에서 바로 수정하고 저장할 수 있는 인라인 편집 기능을 추가해보면 어떨까 생각했다.
MDXEditor 도입과 실패
뷰 모드와 편집 모드를 나누고 관리자 로그인/로그아웃 기능도 붙였다. 그 뒤 인라인에서 MDXEditor로 마크다운을 편집할 수 있게 구현해봤다.
처음에는 편집 기능도 괜찮아 보였고 툴바도 추가할 수 있어서 좋다고 생각했다.
CSS도 맞추며 이것저것 손봤는데 큰 문제가 있었다. MDXEditor가 코드 블록 안의 코드를 JSX로 파싱해서 편집 기능이 망가졌다.
Milkdown으로 리팩토링, 그리고 또 실패
다른 대체제를 찾을 수밖에 없었다. ProseMirror 기반 Milkdown를 찾았는데 확장성이 좋고 슬래시 커맨드도 지원해서 Notion 스타일 편집 경험을 만들 수 있을 것 같았다. 게다가 MD 네이티브 구현도 괜찮아 보여 현재 블로그 구조와 잘 맞겠다고 봤다.
그래서 열심히 리팩토링했다. CSS가 다시 엉망이 됐지만 처음에는 잘 작동하는 듯했다.
문제는 저장할 때 터졌다. 마크다운으로 변환하는 과정에서 내용이 이상하게 바뀌거나 누락되는 경우가 있었다. 특히 테이블 렌더링이 불안정했고 목차(아웃라인) 표시도 오류가 잦았다.
가장 짜증났던 건 한글 입력 버그였다. 한글을 입력하다 보면 커서가 갑자기 맨 앞으로 점프했다. IME 처리가 제대로 안 되는 것 같았다. 핵심 기능인 저장이 불안정하면 에디터로서 의미가 없다고 판단했다.
BlockNote로 리팩토링 결정
마지막으로 BlockNote를 선택했다. 노션을 닮은 스타일의 TipTap 기반 라이브러리다. JSON-마크다운 변환 레이어를 따로 구현해야 했지만 그래도 가장 나은 선택이라고 판단했다. 어차피 아주 무거운 프로젝트도 아니니 이 정도 리소스는 감수할 만하다고 봤다.
React 컴포넌트로 쉽게 통합할 수 있고 문서화도 잘 돼 있었다. 무엇보다 최신 라이브러리라 개발도 활발해서 안정성에 대한 기대가 있었다.
이후에는 버그와의 전쟁이었다. 한글 입력 시 커서가 점프하는 문제는 onChange 핸들러에 디바운스를 넣고 초기 마운트를 무시하도록 처리해 해결했다.
이미지 상대 경로가 표시되지 않는 문제도 있었고 다크모드 CSS와 이중 인코딩, Embed 이미지 미표시, 이미지 삭제 후 저장 미반영 같은 골치 아픈 문제도 이어졌다.
하루를 거의 다 쓰고 나서야 겨우 기능 구현을 마무리했다.
물론 또 버그나 개선해야 할 점들이 발견될테지만....
구현/개선된 기능들
- 핵심 구현 내역
- 패키지:
@blocknote/react,@blocknote/mantine,@blocknote/core - 마크다운 변환:
markdownToBlocks(),blocksToMarkdown()사용
- 패키지:
커스텀 이미지 선택 패널 구현
- 폴더 내 이미지 디렉토리의 이미지를 그리드로 표시하고 선택할 수 있는 패널을 구현했다.
- 이미지 파일이 많아지면 찾기가 힘들어져서 파일명 검색 기능도 추가했다.
- 검색창에 입력하면 실시간으로 이미지 필터링
- 검색 결과 개수 표시
- 대소문자 구분 없이 검색
다크 모드 스타일링 통일
- 슬래시 메뉴, 포맷팅 툴바, 드롭다운 메뉴 모두 통일된 다크 모드 색상을 적용했다.
슬래시 메뉴 커스터마이징
/image커스터마이징 메뉴- 제거된 항목:
- H4, H5, H6 (불필요)
- Toggle Heading 1-3 (마크다운 미지원)
- Emoji, Video, Audio, File
포맷팅 툴바 MD 표준화
- 마크다운 표준 포맷만 유지했다.
- 유지: Bold, Italic, Underline, Strike, Code, Link
- 제거: 텍스트/배경 색상, 정렬 버튼
코드 블록 개선
| 속성 | 값 |
|---|---|
| 폰트 | JetBrains Mono (Google Fonts) |
| 크기 | 13px |
| 라이트 배경 | #f1f5f9 (slate-100) |
| 다크 배경 | #1e293b (slate-800) |
| 테두리 | 없음 |
Bullet Point 스타일 통일
- 마크다운 저장 시
*불릿을-로 자동 변환하도록 후처리를 추가했다. 기존 마크다운 파일을-기준으로 써왔기 때문에 형식을 맞추려는 목적이다.