静态博客做搜索,卡点从来不是”能不能搜”,而是”索引放哪”。托管在第三方要注册账号、构建钩子和免费额度;自己打包 JSON 则全量下载,文章一多就失控。
Pagefind 的思路
构建完成后对 dist 目录跑一次索引:
pagefind --site dist
它会把索引切成很多个小分片,浏览器查询时只下载命中的分片。300 篇文章的典型体积:首页查询只拉几十 KB。没有账号、没有服务端、没有额度,索引就是静态文件,跟着站点一起走 CDN。
接入命令面板
⌘K 唤起的面板只需要十几行代码。第一次打开时动态 import,之后常驻内存:
const pf = await import('/pagefind/pagefind.js');
const res = await pf.search(query);
const data = await Promise.all(res.results.slice(0, 8).map(r => r.data()));
// data[i].meta.title / data[i].excerpt / data[i].url
中文分词的坑
Pagefind 对 CJK 的处理是按字符 bigram 切分,实测中文检索召回没问题,但英文混排的标题建议在正文里保持原样,不要中英之间插空格花活。索引构建后可以用 pagefind --site dist --verbose 看每个页面被切成了什么。
无 JS 兜底
搜索页做了一个 noscript 分支:直接渲染全量文章列表,标题和日期齐全。搜索体验可以降级,找得到内容不能降级——这也是整个站点只用一个第三方脚本(就是 Pagefind 本身)的原因。
结论
对内容型静态站,Pagefind 是目前的最优解:零服务、零账号、体积极小、构建期生成。把”搜索”从一个系统问题降级成了一个构建步骤,这才是静态站该有的样子。