不用后端数据库,给静态博客加一个离线全文搜索:Pagefind 实战
静态博客最大的短板之一,就是没有搜索。文章攒了几十篇之后,读者想找一篇旧文,只能靠翻归档、靠浏览器 Ctrl+F,体验很差。很多人因此觉得“静态站不配拥有搜索”,其实完全可以在不引入数据库、不搭后端服务的前提下,把搜索做成本地离线功能。本文用 Pagefind 做一次实战。
为什么不用后端搜索
常见的搜索方案有三类:第一类是把文章推给第三方搜索服务,按量计费,还要把内容交给外部;第二类是自己搭 Elasticsearch 或 Meilisearch,需要常驻进程和内存,小站点很不划算;第三类是浏览器端全文检索,把索引文件随网站一起发布,搜索完全在用户浏览器里完成,服务器只负责提供静态文件,零运维成本。对个人博客来说,第三类最合适。
Pagefind 是怎么工作的
Pagefind 是一个用 Rust 写的命令行工具,构建时扫描生成的 HTML,把正文切词、建倒排索引,产出若干个体积很小的索引片段和一个 JS 运行时。用户在搜索框输入关键词时,浏览器按需加载相关的索引片段,在本地完成匹配和排序,整个过程不需要向后端发任何请求。
关键点有两个:
- 索引在构建阶段生成,和静态页面一起部署,不需要额外服务;
- 搜索是懒加载的,首页不加载索引,只有用户开始搜索时才拉取相关片段,首屏不受影响。
接入步骤(以 Hugo 为例)
1. 安装 Pagefind
# macOS
brew install pagefind
# 也可以从 GitHub Releases 下载对应平台的二进制
2. 生成索引
在 Hugo 生成站点之后执行:
hugo && npx pagefind --site public
命令会在 public/pagefind/ 目录下生成索引文件,随站点一起部署即可。
3. 在页面里加搜索框
在主题模板合适的位置放一个容器和一段初始化代码:
<link href="/pagefind/pagefind-ui.css" rel="stylesheet">
<div id="search"></div>
<script src="/pagefind/pagefind-ui.js"></script>
<script>
new PagefindUI({
element: "#search",
showSubResults: true,
showImages: false
});
</script>
刷新页面,输入关键词,就能看到带上下文摘录的搜索结果了。
中文要特别注意分词
Pagefind 默认的分词对英文很友好,对中文需要多做一步:中文没有空格,索引粒度直接影响“搜得到还是搜不到”。
- 保持 Pagefind 为较新版本,其中文支持在持续改进;
- 重要的专有名词、产品名,尽量在正文里以完整词组的形式出现一次,避免被切得太碎;
- 上线后用几个真实查询词自测一遍,比如搜“备份”“搜索”“部署”,确认结果里有预期文章,再微调。
如果对中文检索质量要求很高,也可以把文章标题、摘要单独作为权重更高的字段来处理,或者换用支持中文分词更成熟的方案,但对个人博客来说,Pagefind 已经够用。
部署与更新
索引文件是构建产物,部署流程不用变:写文章、重新生成、重新部署,索引随之更新。需要注意两点:
- 不要把 pagefind/ 目录放进部署忽略列表,否则线上没有索引;
- 索引文件会被浏览器缓存,更新文章后如果搜不到新内容,先硬刷新确认,再检查缓存策略。
总结
静态博客加搜索,不必上数据库、不必常驻服务:构建时生成索引,浏览器里完成检索,部署流程几乎不变。对内容量在几百篇以内的个人站点,这套方案的成本和复杂度都刚刚好。下一步可以继续优化搜索框的样式、给结果加高亮,或者把搜索入口放到导航栏更显眼的位置。
- 点赞
- 收藏
- 关注作者
评论(0)