Pagefind 教學:如何為 Eleventy 靜態網站加入純前端搜尋
文章一多,讀者只靠導覽列和分類頁,找舊文就像在咖啡渣裡找關鍵字。這時先別急著架資料庫:對以文章為主的 Eleventy 靜態網站來說,Pagefind 通常已經很夠用。
這篇會帶你弄懂 Pagefind 的工作方式,接著完成 layout 標記、build 後建立索引,以及繁體中文搜尋的驗收。讀完後,你應該能判斷 Pagefind 是否適合自己的網站,也知道搜尋失靈時該從哪裡查起。
目錄
Pagefind 是什麼?
Pagefind 是在 build 後處理靜態 HTML 的搜尋工具。它會讀取網站輸出的 HTML,建立一組可由瀏覽器載入的索引檔;訪客搜尋時,結果在前端計算,不需要另開一個搜尋 API 或資料庫伺服器。
所以它很適合個人部落格、文件站和產品說明站。文章更新後重新 build,索引也跟著重建。反過來說,如果你的資料需要登入權限、個人化結果或即時更新,Pagefind 不是後端搜尋的替代品——咖啡濾紙也不能拿來當資料庫。
開始前先確認三件事
你需要一個能正常輸出 _site/ 的 Eleventy 專案,並確認共用 layout 的 <html> 有語言標記:
<!doctype html>
<html lang="zh-Hant">
<head>
</head>
<body>
</body>
</html>語言標記不是裝飾。Pagefind 會在索引時讀取 <html lang>,依語言分開建立索引;瀏覽器初始化搜尋時,也會依目前頁面的語言載入對應索引。繁體中文網站通常可以使用 zh-Hant,但仍應用實際文章內容測試。
另外,請先單獨確認 Eleventy build 沒有錯誤。Pagefind 只能處理已經產生的靜態檔案,不能替你修好前一步的模板錯誤。
第一步:選擇 Pagefind UI 版本
Pagefind 的搜尋索引和搜尋介面是兩件事。索引先由 CLI 建立,UI 再載入 /pagefind/ 裡產生的資產。
目前常見的兩種 UI 寫法,不能直接混在一起:
- Pagefind 1.4 及更早版本常用 Default UI:載入
pagefind-ui.css、pagefind-ui.js,再用new PagefindUI(...)初始化。 - Pagefind 1.5 開始提供 Component UI:使用
pagefind-component-ui.css、pagefind-component-ui.js和自訂元素,例如<pagefind-modal>。
先看專案的 package.json 版本,再照對應文件操作。本文以 Pagefind 1.4 的 Default UI 示範,因為這是目前專案使用的版本。
在共用 layout 放入 CSS 與搜尋容器:
<link rel="stylesheet" href="/pagefind/pagefind-ui.css">
<div id="search"></div>接著在 JavaScript 中載入並初始化 UI:
const pagefindScript = document.createElement('script');
pagefindScript.src = '/pagefind/pagefind-ui.js';
pagefindScript.onload = () => {
new window.PagefindUI({
element: '#search',
showSubResults: false,
});
};
document.body.appendChild(pagefindScript);你也可以在頁面載入時直接用 <script> 載入;只有在訪客打開搜尋時才載入,則能避免每個頁面一開始都下載搜尋程式。重點是:不論採用哪種載入時機,索引尚未建立前,/pagefind/ 下的檔案都不存在,看到 404 不一定是 UI 寫錯。
第二步:告訴 Pagefind 要索引什麼
Pagefind 預設會處理頁面內容,但你可以用 data-pagefind-body 把範圍縮小,用 data-pagefind-ignore 排除固定介面:
<body>
<header data-pagefind-ignore>
網站導覽
</header>
<main data-pagefind-body>
</main>
<footer data-pagefind-ignore>
頁尾資訊
</footer>
</body>這三個標記各自做一件事:
lang="zh-Hant"提供語言資訊,讓 Pagefind 進行對應的語言處理。data-pagefind-body指定頁面真正要被搜尋的內容。data-pagefind-ignore排除導覽列、頁尾或分享按鈕,避免固定文字污染每一筆結果。
有一個容易漏掉的規則:只要網站任何頁面使用了 data-pagefind-body,沒有這個標記的頁面就不會被索引。因此,如果首頁、分類頁也要出現在搜尋結果裡,它們同樣要標記搜尋主體。
data-pagefind-ignore 是「排除元素」;它不會讓整頁消失。把它放在 header 或 footer 上,文章正文仍然會被索引。
第三步:在 Eleventy build 後建立索引
先建立網站,再把輸出目錄交給 Pagefind。使用專案已安裝並鎖定版本的 CLI,通常比每次用 npx -y 下載最新版更容易重現:
pnpm exec eleventy
pnpm exec pagefind --site _site --glob '**/*.html'成功後,輸出目錄會出現 _site/pagefind/,裡面包含索引資料,以及 UI 需要的 JavaScript 和 CSS。Pagefind 本身沒有搜尋後端;這些檔案部署到同一個靜態網站後,瀏覽器就能載入它們。
如果想快速測試,也可以讓 Pagefind 在建立索引後提供本機靜態伺服器:
pnpm exec pagefind --site _site --glob '**/*.html' --serve這個 --serve 是方便開發時測試的本機伺服器,不是正式環境必須部署的服務。不要直接用 file:// 開啟 HTML,因為瀏覽器的模組載入和 fetch 請求可能受到本機檔案權限限制。
第四步:把流程接進 package.json
手動跑兩個指令可以驗證概念,但很容易忘記第二個。把 Pagefind 接在 Eleventy 後面,每次 build 就會自動更新索引:
{
"scripts": {
"build": "NODE_ENV=production ELEVENTY_PROFILE=true pnpm exec eleventy && pnpm exec pagefind --site _site --glob \"**/*.html\""
}
}實際專案的 build script 可能還有清理、Vite 或其他收尾步驟;請把 Pagefind 放在「所有 HTML 都完成之後」。如果部署平台只執行 Eleventy,卻沒有執行 Pagefind,正式站自然不會憑空長出搜尋索引。
也可以在 Eleventy 的 eleventy.after 事件裡呼叫 Pagefind,但這會讓 Eleventy 設定檔同時負責建站和啟動外部程序。對多數專案而言,package.json 用 && 串接比較容易看懂、除錯,也能確保前一步失敗時不會誤把舊索引當成新成果。
繁體中文搜尋要怎麼驗收?
Pagefind 支援中文的分詞處理,但中文不像英文那樣以空白分隔;搜尋結果仍然取決於索引內容和查詢方式。這不是「加上 lang 就保證什麼都找得到」,所以請用真正的文章做測試。
部署前至少走過這份清單:
- [ ] Eleventy build 成功,沒有模板或資產錯誤。
- [ ]
_site/pagefind/存在,且正式網址能載入/pagefind/下的檔案。 - [ ] 搜尋一個確定存在的文章標題,可以回傳結果。
- [ ] 搜尋兩三個繁體中文詞組,例如「網站安全」或「靜態網站」。
- [ ] 搜尋結果沒有被導覽列、頁尾或分享按鈕的固定文字洗版。
- [ ] 修改文章後重新 build,結果中的摘要已更新。
若網站同時有多種語言,請讓每個頁面的 <html lang> 正確反映內容,不要全部硬寫成同一種語言。Pagefind 會依語言分開索引;標記錯誤,等於把書放進錯的書架,搜尋當然會繞遠路。
常見問題排查
搜尋框出現,卻沒有結果
先看瀏覽器 Network 面板:/pagefind/pagefind-ui.js、/pagefind/pagefind-ui.css 和索引檔是否回傳 404。再確認 Pagefind 指向的是包含 HTML 的輸出目錄,而不是專案原始碼目錄。
中文結果很少
檢查 <html lang> 是否存在且寫對,並用文章內確實出現的詞組測試。也檢查 data-pagefind-body 是否誤放在空容器,或文章所在頁面根本沒有這個標記。不要只因為終端機出現 stemming 相關提示就移除語言標記:中文搜尋仍可運作,只是 Pagefind 不會以英文詞幹還原的方式處理中文。
首頁或分類頁沒有出現在結果裡
這通常是 data-pagefind-body 的範圍規則造成的。只標記文章 layout 時,沒有標記的首頁和分類頁會被排除;在同樣希望被搜尋的頁面補上搜尋主體即可。
搜尋結果一直出現導覽列文字
將不需要搜尋的固定區塊加上 data-pagefind-ignore,刪除舊的 _site/pagefind/ 後重新 build。只改模板、不重建索引,搜尋結果不會自己更新——索引沒有讀心術,只有讀檔術。
本機測試看起來壞掉
確認不是用 file:// 開啟 HTML,也確認 Pagefind 產出的 /pagefind/ 路徑和網站部署的 base path 一致。使用 --serve 或其他靜態檔案伺服器重新測試,通常很快就能分辨是瀏覽器載入問題還是索引內容問題。
結語:先解決搜尋,再考慮升級
對大多數 Eleventy 部落格來說,第一版站內搜尋不需要資料庫。你只要:
- 在 layout 加入與 Pagefind 版本相符的 UI。
- 設定正確的
lang、data-pagefind-body和data-pagefind-ignore。 - 在每次 Eleventy build 後執行 Pagefind。
- 用實際的繁體中文查詢驗收。
這樣就能讓讀者搜尋已部署的文章。未來若真的需要會員權限、個人化排序或即時資料,再評估後端或託管搜尋服務;先把今天的搜尋做好,咖啡才不會冷得太有深度。
參考資料
- Pagefind 官方文件:總覽、安裝與基本整合方式。
- Running Pagefind:說明
--site、--serve等 CLI 用法。 - Customizing the index:說明
data-pagefind-body與data-pagefind-ignore。 - Multilingual Search:說明
lang、多語言索引與中文分詞。 - Pagefind UI Usage:說明 Default UI 的載入和初始化方式。
- Eleventy Configuration Events:查閱
eleventy.after等 Eleventy 事件。

