笔记 / 2026-10-21
静态站点的全文搜索:Pagefind 的取舍
不引入搜索服务的前提下,用 Pagefind 在构建期建立索引,并说明它在体积、中文检索与子路径部署上的边界。
问题
静态站点没有服务端,搜索通常有三条路:接一个托管搜索服务、在客户端加载全量 JSON 做匹配、或者构建期生成倒排索引。
前两条各有明显代价:托管服务引入外部依赖与费用;全量 JSON 在内容增长后会把首屏预算吃光。
方案
Pagefind 走第三条路:构建完成后扫描 HTML,生成分片的索引与元数据;浏览器只在需要时按需加载索引分片,查询在 WebAssembly 中完成。
这个站点的接入方式很简单:集成在构建结束时建立索引,搜索页动态加载 pagefind.js,输入框做 160ms 防抖,结果只渲染标题与摘要。
边界
第一,索引是“构建产物”,内容更新必须重新构建,这也是静态站的常态。
第二,中文检索依赖分词质量。Pagefind 对中文可用,但召回率不如专门的搜索引擎;对这个站点的规模足够。
第三,子路径部署要小心:索引文件的路径必须带 base,否则搜索会 404。项目在集成测试里专门覆盖了这一点。
第四,搜索页本身不应该被索引,robots 与页面标记都要排除。
结论
对中小型内容站,Pagefind 是“成本最低的够用方案”:没有服务、没有密钥、没有月费。代价是索引随构建生成,以及中文召回率的上限。相关决策见 ADR 0005。
实现索引
src/pages/search.astro:搜索页与结果容器。pnpm build:构建后生成 Pagefind 索引。scripts/check-dist.mjs:检查索引与搜索页产物。