JavaScript API
Pagefind 的搜索能力可以直接通过浏览器 JavaScript 调用。这样可以保留自己的搜索弹窗、输入框、结果列表和交互逻辑。
动态导入
Pagefind 生成索引后,会在输出目录中提供搜索入口脚本。本项目把搜索资产输出到 /_pagefind/:
const pagefind = await import("/_pagefind/pagefind.js");
可以手动初始化,也可以等第一次搜索时自动初始化:
await pagefind.init();
执行搜索
const pagefind = await import("/_pagefind/pagefind.js");
const search = await pagefind.search("静态搜索");
搜索结果对象里的 results 默认只包含轻量信息。真正的标题、URL、摘要和元数据需要按需加载:
const rows = await Promise.all(
search.results.slice(0, 8).map((result) => result.data())
);
结果数据通常包含:
| 字段 | 说明 |
|---|---|
url |
结果页面 URL |
excerpt |
带高亮标记的摘要 |
plain_excerpt |
不带高亮 HTML 的纯文本摘要 |
meta.title |
页面标题 |
meta.image |
页面图片元数据 |
sub_results |
页面内更具体的命中片段 |
一个最小搜索框
<input id="search" type="search" placeholder="搜索文档">
<div id="results"></div>
<script type="module">
const input = document.querySelector("#search");
const results = document.querySelector("#results");
let pagefindPromise;
function loadPagefind() {
pagefindPromise ||= import("/_pagefind/pagefind.js");
return pagefindPromise;
}
input.addEventListener("input", async () => {
const query = input.value.trim();
if (!query) {
results.innerHTML = "";
return;
}
const pagefind = await loadPagefind();
const search = await pagefind.search(query);
const rows = await Promise.all(search.results.slice(0, 5).map((item) => item.data()));
results.innerHTML = rows
.map((row) => `<a href="${row.url}"><strong>${row.meta.title}</strong><p>${row.excerpt}</p></a>`)
.join("");
});
</script>
excerpt 已经适合放入结果摘要,但其他原始字段如果来自不可信内容,仍应在模板层做转义。
输入防抖
搜索框通常会随着用户输入不断触发查询。可以自己写防抖,也可以使用 pagefind.debouncedSearch()。如果用户很快输入了新内容,较旧的防抖搜索可能返回 null,渲染前需要判断。