Astro 정적 사이트에 Pagefind 검색 붙이기 — 빌드 파이프라인과 한글 형태소의 한계
정적 블로그에 Pagefind 기반 사이트 검색을 통합하면서 겪은 빌드 순서 문제와 한글 검색의 형태소 분석 한계를 실제 설정과 함께 정리한다. 검색이 '동작은 하지만' 아쉬운 지점이 어디인지가 핵심이다.

정적 사이트(SSG)의 가장 큰 약점 중 하나가 “검색”이다. 서버가 없으니 검색 인덱스를 만들고 클라이언트에서 조회해야 한다. 이 블로그는 Pagefind를 선택했다. 빌드 후 생성된 정적 파일을 대상으로 검색 인덱스를 만들고, 브라우저에서 pagefind.js를 로드해 검색하는 방식이다. 통합 과정에서 빌드 순서, 한글 형태소, 지연 로딩이라는 세 가지 이슈를 만났다.
사실: Pagefind 통합의 구조
package.json의 빌드 스크립트는 이렇게 구성되어 있다.
{
"scripts": {
"build": "astro build && pagefind --site dist/"
}
}
astro build로 정적 사이트를 생성한 뒤, pagefind --site dist/로 dist/ 디렉터리를 스캔해 검색 인덱스를 만든다. Pagefind는 dist/pagefind/ 디렉터리에 인덱스 파일을 생성한다.
프론트엔드(Search.astro)는 검색창을 열 때 지연 로딩으로 pagefind.js를 로드한다.
function loadPagefind(query) {
var script = document.createElement('script');
script.src = '/pagefind/pagefind.js';
script.onload = function() {
pagefind.init().then(function() {
pagefindLoaded = true;
if (query) {
doSearch(query);
}
});
};
document.head.appendChild(script);
}
검색어를 입력하면 300ms 디바운스 후 pagefind.search(query)를 호출하고, 결과를 최대 10개까지 렌더링한다.
원인: 빌드 순서가 틀리면 인덱스가 없다
처음에는 pagefind --site dist/를 astro build 앞에 두는 실수를 했다. 당연히 dist/가 아직 없어서 “Directory not found” 에러가 났다. 이건 단순한 실수였지만, 더 미묘한 문제가 있었다.
Pagefind는 dist/의 HTML 파일을 스캔해서 인덱스를 만든다. 그런데 이 블로그는 wrangler.jsonc에서 html_handling: drop-trailing-slash를 사용한다. 즉 /posts/foo/가 /posts/foo로 서빙된다. Pagefind가 생성하는 인덱스의 URL도 이 규칙을 따라야 하는데, Pagefind는 빌드 시점의 파일 구조를 기준으로 URL을 생성하므로 dist/posts/foo/index.html을 /posts/foo/로 인덱싱한다.
이러면 사이트에서 /posts/foo(슬래시 없음)로 접근할 때 검색 결과 링크가 /posts/foo/(슬래시 있음)로 나가서 404가 발생할 수 있다. Cloudflare Workers Static Assets의 drop-trailing-slash 설정이 이 URL을 다시 정규화해주긴 하지만, 검색 결과 링크가 항상 정상 동작한다고 보장할 수는 없다.
평가: 한글 검색의 형태소 분석 한계
Pagefind는 기본적으로 형태소 분석(stemming)을 지원하지 않는 언어가 있다. 빌드 로그에서 이 경고를 확인했다.
Note: Pagefind doesn't support stemming for the language ko.
Search will still work, but will not match across root words.
한국어는 교착어라서 “검색”과 “검색하다”, “검색의”가 서로 다른 단어로 인덱싱된다. 영어는 “search”, “searches”, “searching”이 “search”로 묶이지만, 한국어는 그렇지 않다.
실제로 이 블로그에서 “전세”를 검색하면 “전세”가 정확히 포함된 글만 나오고, “전세가”, “전세보증금” 같은 파생어는 나오지 않을 수 있다. 이건 Pagefind의 한계라기보다 한국어 검색의 일반적인 문제다. 형태소 분석을 지원하는 검색 엔진(Elasticsearch의 Nori, Meilisearch 등)을 쓰면 해결되지만, 정적 사이트에서 그런 무거운 엔진을 쓰는 건 과하다.
부연: 지연 로딩과 UX 트레이드오프
Pagefind 인덱스는 사이트 규모에 따라 수백 KB에서 수 MB까지 커질 수 있다. 이 블로그는 현재 124페이지, 약 28,851단어를 인덱싱한다. 이 정도면 초기 로딩에 포함하기엔 부담스럽다.
그래서 Search.astro는 검색창을 처음 열 때 pagefind.js를 로드한다. 이 방식의 장점은:
- 초기 페이지 로딩에 영향 없음 — 인덱스 파일을 첫 화면에서 다운로드하지 않음
- 사용자가 검색할 때만 리소스 사용 — 검색 기능을 안 쓰는 방문자에게 불필요한 다운로드 없음
단점은:
- 첫 검색 시 지연 —
pagefind.js로드 + 인덱스 파싱 시간이 추가됨 - 오프라인/느린 네트워크에서 검색 불가 — CDN에서
pagefind.js를 못 받으면 검색이 동작하지 않음
이 블로그는 “검색은 보조 기능”이라는 판단으로 지연 로딩을 유지했다. 만약 검색이 핵심 기능이라면 인덱스를 미리 로드하거나, 서버 사이드 검색(예: Cloudflare Workers + D1)을 고려했을 것이다.
남긴 체크리스트
- 빌드 순서:
astro build→pagefind --site dist/순서를 지킬 것 - URL 정규화:
drop-trailing-slash설정과 Pagefind 인덱스 URL의 불일치를 확인할 것 - 한글 검색: 형태소 분석 미지원을 인지하고, 검색어를 정확히 입력하도록 UX를 설계할 것
- 지연 로딩: 첫 검색 지연을 감수할지, 인덱스 선로딩을 할지 사이트 규모에 따라 결정할 것
Pagefind는 정적 사이트에 “충분히 쓸 만한” 검색을 붙여주는 도구다. 다만 “완벽한 검색”을 기대하면 안 되고, 한글 형태소와 URL 정규화라는 두 가지 한계를 알고 쓰면 된다.
출처
- Pagefind 공식 문서 — Getting Started — 빌드 파이프라인, 언어 지원 (열람: 2026-08-06)
- Pagefind GitHub — 한국어 stemming 미지원 이슈 — ko 언어 stemming 관련 (열람: 2026-08-06)
- 내부 실측:
package.json의build스크립트 —astro build && pagefind --site dist/ - 내부 실측:
npm run build로그 — “Indexed 124 pages, Indexed 28851 words”, “Pagefind doesn’t support stemming for the language ko” - 내부 실측:
src/components/Search.astro— 지연 로딩, 300ms 디바운스, 최대 10개 결과 렌더링