스크립트 몇 줄로 어느 페이지에나 붙는 댓글 위젯
가볍게 붙이고, 원하는 대로 고쳐 쓰는 위젯
2026/09/23 17:36스크립트 몇 줄로 어느 페이지에나 붙는 댓글 위젯
3편에서는 댓글 API가 무엇을 허락하고 무엇을 막는지 정리했다. 이번에는 그 API를 블로그 화면에 그려 주는 위젯을 다룬다. 위젯이 어떻게 페이지에 붙고, 어떻게 가볍게 만들었고, 어떻게 배포하는지 차례로 적고, 마지막 에이전틱 코딩 노트에는 코딩 에이전트인 Claude Code와 위젯을 어떻게 만들었는지 적는다.
위젯이 동작하는 방식

블로그 쪽에서 할 일은 세 가지다. 위젯의 CSS와 스크립트를 불러오고, 댓글을 띄울 자리에 data-orb-container가 붙은 div를 두고, OrbitHall.init을 한 번 부른다. 설치 코드는 1편에 있다.
스크립트는 전역에 OrbitHall 객체 하나만 만든다. init이 불리면 페이지에서 댓글 자리를 모두 찾아, 자리마다 적힌 slug로 댓글을 불러와 그린다. 문구는 한국어가 기본이고, locale: 'en'을 넘기면 영어로 바뀐다. API가 돌려주는 에러도 두 언어의 안내 문구로 바꿔 보여 준다.
Preact와 Bun으로 가볍게
위젯은 다른 사람의 페이지 안에서 도는 코드라서, 무엇보다 가벼워야 했다. 화면은 React와 거의 같은 방식으로 쓰면서 크기는 훨씬 작은 Preact로 만들고, 번들은 Bun으로 묶었다.
결과물은 스크립트 하나(약 30KB)와 스타일시트 하나(약 7.5KB)다. 스크립트는 불러오는 즉시 실행되는 함수 하나로 감싸져 있어서 페이지의 다른 코드와 섞이지 않는다. 페이지가 React로 만들어졌든 그냥 HTML이든 상관없이, 태그 몇 줄로 불러오면 끝난다.
스타일은 덮어쓸 수 있게
위젯의 스타일은 블로그의 스타일과 섞이지 않도록 모든 클래스 이름을 orb-로 시작하게 했다. 색과 간격, 글꼴, 테두리는 --orb-로 시작하는 CSS 변수로 모아 두었다.
:root {
--orb-primary-color: #171717;
--orb-font-family: 'Pretendard', sans-serif;
--orb-border-radius: 0.75rem;
}
위젯을 쓰는 사이트는 이 변수만 덮어써도 자기 사이트에 맞는 색과 모양으로 바꿀 수 있다. 원하는 경우, 위젯을 그대로 쓰지 않더라도 클래스 이름 규칙을 따라 스타일을 다시 짜서 자기만의 모양으로 고쳐 쓸 수 있다. 이게 처음부터 의도한 기능 중 하나였다.
페이지 이동에도 붙는 위젯
Next.js 같은 SPA에서는 다른 글로 이동해도 페이지가 새로 로드되지 않는다. 새 글의 댓글 자리는 새로 생기는데, init은 이미 첫 페이지에서 한 번 불린 뒤다. 처음 불렸을 때 있던 자리만 찾는 위젯이라면, 두 번째 글부터는 댓글창이 뜨지 않는다.
그래서 위젯은 init 뒤에도 페이지의 변화를 계속 지켜보다가(MutationObserver), 새로 생긴 댓글 자리를 찾으면 그 자리에 붙는다. 같은 자리가 재사용되면서 slug만 바뀌는 경우도 감지해 그 글의 댓글을 다시 불러온다. init이 두 번 불려도 한 번만 동작한다. 어떤 방식으로 만든 페이지에든 붙는 위젯이라면 처음부터 챙겨야 할 부분이었다.
댓글 목록은 최신순으로
입력칸은 목록 맨 위에 두고, 댓글은 최신순으로 보여 준다. 댓글을 다 훑어보지 않아도 바로 쓸 수 있고, 방금 쓴 댓글은 입력칸 바로 아래에 나타난다. 답글은 각 댓글 아래에서 오래된 순으로 이어져 대화 흐름을 해치지 않는다. 한 번에 50개씩 보여 주고, 더 있으면 목록 아래에 "댓글 8개 더 보기"처럼 남은 개수를 알려 주는 버튼이 나타난다.

배포는 GitHub와 jsDelivr로
위젯 파일은 따로 서버에 올리지 않는다. GitHub 저장소에 있는 파일을 jsDelivr라는 CDN이 그대로 내려 준다. 서비스 비용을 들이지 않으면서, 널리 쓰이는 CDN이라 안정성도 믿을 만하다고 봤다.

버전은 v1.2.0 같은 semver git 태그로 낸다. 릴리스할 때마다 배포 스크립트가 main의 최신 커밋 위에 빌드 결과물만 더한 커밋을 만들고, 그 커밋에 태그를 붙여 올린다. 빌드 결과물은 main에 섞이지 않고 태그가 가리키는 릴리스 커밋에만 있다. 작업 트리가 깨끗하지 않거나 같은 버전의 태그가 이미 있으면 스크립트는 멈춘다.
jsDelivr는 태그로 만든 버전 주소(@1.2.0)를 1년 동안 바뀌지 않는 파일로 다룬다. 한 번 낸 버전은 CDN이 바뀌지 않게 지켜 주니, 블로그는 정확한 버전 주소를 고정해 두고 새 버전을 확인한 뒤에 주소를 올린다. @1처럼 범위로 쓰면 1.x의 새 버전을 알아서 따라가지만, 새 버전이 CDN에는 최대 12시간, 브라우저에는 최대 7일 늦게 반영된다.
에이전틱 코딩 노트
위젯도 백엔드와 비슷한 집중도로 에이전트와 작업했다. 프론트엔드 기술은 더 익숙한 영역이었지만, 기술적 해상도에 집중하기보다는 그 집중력을 눈에 보이는 결과물에 투자하고, 더 기민하게 다음 단계로 넘어가려 했다. 이 프로젝트의 중심은 어디까지나 댓글 서비스이고, 위젯은 부수적 기능이라고 생각했다.
위젯은 계획 문서를 쓰고 사흘 만에 블로그에 붙었다. SPA 라우팅 대응처럼 처음부터 인지하고 있던 기능들도 실제 블로그에 붙여 보면서 다듬어야 했다. 개발 단계에서는 잘 돌던 코드도 실제로 써봐야 드러나는 결함이 있었다.
나중에는 위젯을 여러 UI와 테마로 제공할 생각도 해보고 있다. 클래스 이름과 CSS 변수를 규칙으로 정해 둔 이유 중 하나이기도 하다.
다음 편에서는 사이트를 등록하고 댓글을 확인하는 어드민을 다룬다.
저장소
- 위젯 소스: june20516/orbithall/widget