세 시간 안에 리텐션 인프라를 여러 사이트에 심다
목차
오후 세 시쯤 슬랙을 닫고 에디터를 켰을 때 원래 계획은 딱 하나였다. 신규 사이트 하나를 뼈대만 세우고 마무리하는 것. 근데 그게 생각보다 빨리 끝나버렸고, 거기서 나온 "카운트다운 + 북마크 + 알림" 패턴을 다른 두 서비스에도 그대로 이식하고 싶다는 욕심이 생겼다. 결국 세 시간 동안 세 개의 레포를 오가며 공통 리텐션 도구를 박았다.
1. 신규 사이트 킥오프 — 8개 로케일, 8개 툴
처음 한 시간은 완전히 새로운 프로젝트였다. 클릭-속도-테스트 허브를 글로벌 멀티링구얼로 만든다는 요건인데, 아스트로 기반으로 8개 로케일을 처음부터 구성했다. 이미 다른 사이트에서 비슷한 i18n 설정을 수십 번 해봤으니 세팅 자체는 빠르게 끝났다. 그 자리에서 About / Contact 페이지 8벌과 푸터 법적 링크 4종도 한 번에 달았다.
작업이 끝나자마자 ops 문서(hedvion-CLAUDE.md, sites-detail.md)에 해당 사이트를 등록했다. 외부 apex 도메인, cms_site ID, 법적 페이지 구성까지 기록해두는 게 팀 기준이라 빼먹으면 나중에 인프라 담당이 헤맨다. 이건 귀찮아도 그날 커밋에 붙이는 게 원칙이다.
2. 드롭스 페이지에 리텐션 도구 심기
신규 사이트 뼈대가 올라가고 나서 다음으로 눈이 간 곳은 기존에 운영 중인 팝마트 드롭스 페이지였다. 유저가 한 번 들어와서 "아 이거 다음 주에 나오는구나" 확인하고 그냥 나가버리는 게 계속 걸렸다. 재방문을 유도할 훅이 없었던 것.
이번에 추가한 건 세 가지다:
- 라이브 카운트다운 — 드롭 일자까지 남은 시간 실시간 표시
- 캘린더 등록 — "Add to Calendar" 버튼으로 구글/애플 캘린더에 바로 추가
- 워치리스트 —
localStorage에 저장, 다음 방문 때 상태 유지
여기서 한 가지 삽질이 있었다. 봇이 팝마트 페이지를 렌더링할 때 드롭 날짜(publishTime 필드)를 아예 안 잡고 있었다. 서버에서 직접 프로브해보니 해당 필드가 페이지 응답에 분명히 있었다. 봇 파서에서 그냥 무시하고 지나치고 있었던 것. popmart_render.js 패치 하나로 해결됐지만, 이걸 발견 못 했으면 카운트다운이 날짜 없이 빈 상태로 뜰 뻔했다.
시각적으로도 문제가 있었다. 다음 드롭 배너의 그라디언트가 너무 옅어서 흰색 텍스트가 WCAG AA를 통과 못 했다. 그라디언트 깊이를 올리고 칩 컬러를 어둡게 조정해서 대비를 맞췄다.
3. kpopdex — 팔로우 + 컴백 카운트다운 전면 이식
드롭스 작업을 마치고 나니 자연스럽게 kpopdex로 손이 갔다. 구조가 비슷하다. 유저가 그룹 페이지에 들어와서 컴백 일정 확인하고 나가버린다. 재방문 이유가 없다. 그래서 드롭스에서 만든 패턴을 그대로 들고 왔다.
먼저 그룹 페이지에 팔로우 버튼 + 다음 컴백 라이브 카운트다운 + 캘린더 추가를 넣었다. 팔로우 상태는 localStorage에 저장해서 서버 계정 없이도 동작한다. KST 기준으로 시간을 앵커링하는 게 중요했다 — 컴백 일정이 한국 시간 기준이니까 브라우저 로컬 타임존으로 계산하면 해외 유저한테 하루 차이가 날 수 있다.
그다음 멤버 페이지에도 같은 컴포넌트를 붙였다. 그룹과 멤버 양쪽에 중복 코드가 생기는 게 싫어서 FollowCountdown.astro를 공유 컴포넌트로 분리했다. 이 컴포넌트 하나가 그룹 컨텍스트/멤버 컨텍스트 양쪽을 처리한다.
FollowCountdown.astro
├── props: entity (group | member), nextComeback, lang
├── localStorage key: follow_${entity.id}
└── countdown: KST-anchored, 8-lang label
마지막으로 /following 페이지를 만들었다. 유저가 팔로우한 그룹/멤버를 한 화면에서 볼 수 있는 개인 컴백 허브다. 8개 언어 지원, noindex 처리(개인화 페이지라 검색엔진에 올릴 필요 없다). 네비게이션에 ★ 링크도 달았다.
여기서 또 하나 버그가 터졌다. /following 페이지가 예정된 컴백이 있는 그룹만 표시하고 있었다. 팔로우했는데 현재 컴백 일정이 없는 그룹은 목록에서 아예 사라졌다. 발견하고 보니 필터 로직이 "다음 컴백 데이터가 있는 경우만" 렌더링하도록 짜여 있었던 것. 컴백 없으면 'no comeback yet' 텍스트를 보여주는 방식으로 수정했다.
이 세 시간에서 배운 것
| 반복된 패턴 | 공통 요소 |
|---|---|
| 드롭스 카운트다운 | KST 앵커링, localStorage, Add-to-Cal |
| 그룹 컴백 카운트다운 | KST 앵커링, localStorage, Add-to-Cal |
| 멤버 컴백 카운트다운 | 위와 동일 (공유 컴포넌트) |
세 군데에서 같은 패턴을 세 번 구현하면서 든 생각은, 이게 이제 "플랫폼 레벨 컴포넌트"가 될 타이밍이라는 것이다. 각 사이트마다 조금씩 다른 도메인 컨텍스트를 props로 받는 범용 카운트다운+팔로우 컴포넌트를 ops 레벨에서 관리하면 다음 사이트에 붙일 때 복붙이 아니라 임포트 하나로 끝날 수 있다.
그리고 오버플로 버그(좁은 화면에서 가로 스크롤 발생)나 카운트다운 스타일이 런타임 빌드 후 적용 안 되는 버그 같은 것들은 항상 "그럴 거라고 생각도 못 했던" 곳에서 나온다. 기능 커밋 직후 실기기에서 빠르게 확인하는 습관이 없었으면 배포 후에 발견했을 것들이다. 이런 류의 픽스를 feature 커밋 바로 다음에 붙일 수 있었던 건, 중간에 딴 작업으로 컨텍스트 스위칭 안 하고 그 흐름 안에 있었기 때문이다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.