使用 pagefind 添加博客搜索功能
这周用 pagefind 给博客添加一个 搜索页面,如果你感兴趣可以搜索看看 (ノ>ω<)ノ
一直都想给博客添加一个搜索功能,加上最近开始写周刊,里面整理了不少的链接,有时候我想找点东西,能够搜索的话就会方便很多。
以前尝试过 algolia ,但配置起来有点麻烦,也显得很重,效果并不满意。
这周看到了一个开源项目 pagefind,它可以对构建好的 HTML 进行索引和搜索,配置简单,开箱即用,没有额外的第三方服务,很符合我的需要。
关于 pagefind
Pagefind 是一个完全静态的搜索库,其目标是在大型网站上运行良好,同时尽可能少地占用用户带宽,并且无需托管任何基础设施。
Pagefind 的目标是,拥有数万个页面的网站应能让用户在浏览器中进行搜索,同时尽可能减少带宽消耗。
Pagefind 的搜索索引被分割成若干块,因此在浏览器中进行搜索只需加载搜索索引的一小部分。
Pagefind 可以在一个 10,000 页的网站上运行全文搜索,包括 Pagefind 库本身在内的总网络有效载荷不到 300kB。 对于大多数网站来说,这将接近 100kB。
pagefind 的一些特点:
- 零配置支持多语言网站
- 使用 NodeJS 索引库索引 任何内容(例如 PDF、JSON 文件或字幕)
- 以相同的低带宽占用提供所有功能
对我来说,它最大的优点就是配置简单,不依赖第三方服务,而且搜索效果也不错。
在 Weekly#11 中分享过一篇文章,里面的观点我觉得说的很对:
入门(Getting Started)不应该是在构建产品之后才考虑的问题。入门就是产品!
我认为这值得重构你的整个产品,以便实现快速入门。去掉强制配置。让设置 API 令牌变得极其简单。消除所有障碍。让用户能够在几分钟内在他们的笔记本电脑上使用你的产品。
你可能会说,我不知道,"谁在乎懒惰的用户"。那就让我靠在豆袋椅上,打开一袋多力多滋,解释一下吧:
目前有 7,000,000,000 种开发工具。用户没有那么多精力和耐心去深入了解你的 LRU 缓存 NPM 包或其他东西有什么不同。抱歉了!
It's hard to write code for computers, but it's even harder to write code for humans!
配置 pagefind
配置 pagefind 很简单,你只需要两步:
- 执行
npx -y pagefind --site publish
生成索引,其中publish
是你的静态页面存放的目录。 - 引用对应的 CSS,JS,并且添加一个 DOM 元素让 pagefind 挂载
<link href="/pagefind/pagefind-ui.css" rel="stylesheet"> <script src="/pagefind/pagefind-ui.js"></script> <div id="search"></div> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({ element: "#search", showSubResults: true }); }); </script>
这样你就拥有搜索功能了 ヾ(´∀ ˋ)ノ
下面分享一下我是如何集成的。
CI/CD 中添加索引指令
我的博客1是部署在 Netlify,我只需要在构建的最后,添加一行执行索引的指令就完成索引了。
#!/bin/bash # Enable command printing (debug mode) set -x # Only build when `publish` change git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF publish # index.xml is for https://www.v2ex.com/xna cp -f publish/rss.xml publish/index.xml + # see: https://pagefind.app/docs/multilingual/#opting-out-of-multilingual-search + npx -y pagefind --site publish --force-language zh-CN # Disable debug mode set +x
如果你仔细看的话,会发现我的指令添加了 --force-language zh-CN
的 option,这会告诉 pagefind 要将不同语言的页面都生成到同一个索引里。
pagefind 的默认逻辑是按照语言各自建立索引,当你的页面的 lang 是 en 的时候,它只会检索 en 页面对应的索引,而不会检索 zh-CN 页面的索引。
但是我希望在一个统一的地方,能够搜索到我博客所有的内容,因此我需要它将不同语言的页面索引放到一起。
引用 findpage 资源
相比于在文章页面上添加搜索,我更倾向于一个独立的搜索页面,避免搜索结果影响文章页面的布局。
单独一个页面,在我不需要的时候也可以轻易移除。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Search</title> <meta name="author" content="Spike Leung" /> <meta name="description" content="""" /> <meta name="generator" content="Org Mode" /> <link rel="stylesheet" href="../styles/style.css" type="text/css"/> <link rel="icon" href="/favicon.ico" type="image/x-icon"> <link href="/pagefind/pagefind-ui.css" rel="stylesheet"> <script src="/pagefind/pagefind-ui.js"></script> </head> <body> <div id="search"></div> <script> window.addEventListener('DOMContentLoaded', (event) => { new PagefindUI({ element: "#search", showSubResults: true, showImages: false }); }); </script> </body> </html>
页面上我设置了 lang="zh-CN"
,findpage 会基于 lang 去匹配索引和组件的多语言文字。
之前我的页面都是 lang="en"
,pagefind 将页面按照 en 索引,导致我搜索不到任何内容。
因此我也更新了博客页面的 lang 属性,从 en 改为了 zh-CN,这样对于使用屏幕阅读器的人也会友好一点。
另外我将 showIamges
设置成了 false,因为我的博客文章基本没有封面图,图片还会增加搜索时的带宽消耗。
写在最后
如果你还有更好的搜索服务,欢迎分享 (゚∀。)
感谢 pagefind 提供这样简单好用的搜索服务!\m/ >_< \m/
如果你也有搜索静态页面的需要,试试看吧!
Footnotes:
如果你对我的博客是如何搭建感兴趣,可以看 使用 org-publish 发布博客 (≖ᴗ≖๑)