공개 블로그(former-force) 클라이언트 사이드 검색 계약. 장문 없음.

관련 링크
허브 Astro 블로그
결정 로그 ‣
CMS ‣
캐시·리미트 ‣
Figma EWt5VrwYVBpTAfXpqJnRah
Search Desktop 197:332
Search Mobile 197:387
레포 cpt4567/former-force

1. 왜 CSR 검색인가

전제 결론
Astro 정적 prerender 배포 서버 검색 API 없음이 기본
글 SSOT = Notion · 빌드타임 fetch 검색 인덱스도 빌드 산출물
URL q만 바꿔 결과 갱신 새로고침 없이 브라우저 필터

서버에 Notion 토큰을 둔 런타임 검색은 1순위 아님(리미트·지연). 인덱스는 빌드 때 만들고, 클라이언트에서 필터한다.


2. 권장 스택 후보

후보 요지 선택 기준
Pagefind Astro/정적 HTML 인덱싱 · 번들·UI 옵션 본문 전문 검색·설치 단순 · HTML 산출물 기준
MiniSearch + JSON index 빌드 시 title/tags/slug/excerpt/body JSON → 브라우저 로드 필드 제어·태그칩 병행·페이로드 최소화에 유리

기본 권장: 필드·태그 계약을 Posts 메타와 맞추기 쉬우면 MiniSearch+JSON. 본문 전문·유지보수 최소면 Pagefind. 둘 중 하나만 채택(중복 인덱스 금지).


3. 빌드 산출물 · 인덱스 필드

항목 계약
생성 시점 astro build (Published Posts만)
산출 경로 (제안) public/search/ 또는 dist/.../search/ — 구현 시 레포에 확정
필수 필드 title · tags · slug · excerpt
선택 필드 body(또는 본문 일부) · date · series
결과 URL /posts/[slug]
소스 Notion Posts Published (캐시 경로는 ‣)

4. UI 계약

항목 값
진입 Posts SearchField → /search
쿼리 /search?q= (클라이언트에서 q 반영)
단축키 ⌘K (Windows: Ctrl+K) → /search 포커스
Figma Desktop 197:332
Figma Mobile 197:387
빈 상태 q 없음 · 안내 카피
로딩 인덱스 최초 로드만 · 아래 게이트
결과 0건 empty 카피 · 태그/전체 글 유도
태그칩 /tags/[tag]와 병행 (검색과 필터 충돌 없이)
테마 dark-only · shell/Ink Teal 토큰

5. 스켈레톤 게이트

인덱스/결과 전환이 <300ms면 스켈레톤 생략. 그 이상만 quiet 스켈레톤(VT 계약과 동일 톤).