给 Zola 博客添加中文全文搜索
Zola 自带的搜索索引基于简单的关键词匹配,对中文的支持不够理想——中文需要分词才能准确搜索。而 Pagefind 是一个专门为静态站点设计的搜索工具,内置对中日韩 (CJK) 文字的支持,索引构建快,前端体积小。
本博客第一篇就提到了 Pagefind,但一直没有真正用上。这次我基于 serene 主题,给它接入了 Pagefind 的中文搜索。
安装 Pagefind
Pagefind 以 npm 包形式发布,但实际调用的是原生二进制。最简单的用法:
npm install -g pagefind
安装后在项目里跑:
zola build
pagefind --site public
它会分析 public/ 目录中所有 HTML 文件,生成搜索索引到 public/pagefind/。
如果遇到 SyntaxError: Unexpected token '?' 的错误,说明系统的 Node.js 版本太旧(低于 14)。Pagefind 的 npm 包装在 node_modules/@pagefind/linux-x64/bin/pagefind_extended,可以直接调用这个原生二进制。
集成搜索 UI
Pagefind 自带一个搜索界面组件,包含搜索框、结果列表和高亮功能。只需在页面中加载它的 CSS 和 JS。
Serene 主题提供了 _head_extend.html 扩展点,会注入到每个页面的 <head> 中。我利用这个文件做了三件事:
1. 加载 Pagefind 资源和搜索覆盖层
<link href="/pagefind/pagefind-ui.css" rel="stylesheet">
<div id="search-overlay" hidden>
<div class="search-modal">
<div id="search"></div>
</div>
</div>
<script src="/pagefind/pagefind-ui.js"></script>2. 初始化搜索组件
const ui = new PagefindUI({ element: '#search', showSubResults: true });3. 添加快捷键和按钮
支持的打开方式:点击页面右下角的搜索按钮、按 Ctrl+K(Mac 上 Cmd+K),或点击首页导航栏的搜索图标。按 Esc 或点击遮罩层关闭。
每次打开搜索时,输入框会自动获得焦点,可以直接打字搜索。
适配暗色模式
Pagefind 的 UI 默认是亮色主题。为了适配 serene 的暗色模式,我通过 CSS 变量来覆盖 Pagefind 的颜色:
.pagefind-ui__search-input {
background: var(--bg-color);
color: var(--text-color);
border-color: var(--text-decoration-color);
}
这样当用户切换暗色模式时,搜索框的颜色也会随之变化。
中文搜索效果
Pagefind 会自动检测页面语言。本博客的中文内容被正确识别,搜索时可以进行中文分词。实测搜索「Zola」「主题」「博客」等关键词都能精确匹配到对应文章。
Pagefind 的搜索特性:
- 模糊匹配:大小写不敏感,支持拼写纠错
- 子标题结果:
showSubResults可以展开到段落级别 - 多语言:自动按语言分索引,不会混检
- 轻量:前端 JS 约 30KB(gzip 后)
完整构建流程
加入搜索后,构建命令变为两步:
zola build # 生成静态页面
pagefind --site public # 构建搜索索引
pagefind 命令必须在 zola build 之后执行,因为它读取的是生成好的 HTML 文件。
我把这个流程写到了 AGENTS.md 中,避免下次忘记先后顺序。
总结
从安装到集成完成大约花了 20 分钟:
| 步骤 | 时间 |
|---|---|
| 安装 Pagefind | 3 分钟 |
| 编写搜索覆盖层 | 8 分钟 |
| 适配暗色模式 | 4 分钟 |
| 测试调优 | 5 分钟 |
Pagefind 的中文搜索能力超出了我的预期。它不依赖任何后端服务,构建后纯静态运行,非常适合 Zola 这类静态站点生成器。
如果你也想给自己的博客加上搜索,Pagefind 是目前最省心的方案,尤其是需要支持中文的时候。