[Pagefind] Astroの静的サイトに全文検索を後付けする
TechWordPress には検索機能が標準で付いていますが、Astro の静的サイトには当然ありません。 そこで Pagefind を使って全文検索を後付けしました。サーバー不要・ビルド時にインデックスを作る方式で、静的サイトと相性抜群です。
Pagefind とは
- ビルド済みの HTML を読み込んでインデックスを作る静的検索ライブラリ
- 実行にサーバーや API は不要。インデックスとJS/CSSを配信するだけ
- 検索UI(
pagefind-ui)も同梱されている
つまり「サイトをビルド → 出来上がった dist/ を Pagefind に食わせる」だけで検索が付きます。
インストールとビルド設定
npm i -D pagefind
ポイントは、Astro のビルドが終わった後に Pagefind を走らせること。package.json の build スクリプトを繋げておきます。
{
"scripts": {
"build": "astro build && pagefind --site dist"
}
}
pagefind --site dist が dist/ を走査して、dist/pagefind/ にインデックスと UI 一式(pagefind-ui.js / pagefind-ui.css など)を生成します。
検索UIを設置する
サイドバーなどに、UI を差し込むための要素と Pagefind UI の読み込みを置きます。
---
// src/components/SearchWidget.astro
---
<div id="search"></div>
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
<script is:inline src="/pagefind/pagefind-ui.js"></script>
<script is:inline>
window.addEventListener('DOMContentLoaded', function () {
new PagefindUI({
element: '#search',
showSubResults: false,
showImages: false,
translations: {
placeholder: '記事を検索...',
zero_results: '「[SEARCH_TERM]」に一致する記事が見つかりませんでした',
},
});
});
</script>
translations で日本語化できます。[SEARCH_TERM] は検索語に置換されるプレースホルダーです。
<script>にis:inlineを付けているのは、Astro のバンドル対象から外してそのまま出力するためです(/pagefind/...はビルド後に生成される外部アセットなので、バンドルさせない)。
インデックスの対象を絞りたいとき
デフォルトでは各ページの本文をまるごとインデックスします。ナビやサイドバーまで拾ってしまうのが気になる場合は、記事本文を囲む要素に data-pagefind-body を付けると、その範囲だけをインデックス対象にできます。
<article data-pagefind-body>
<slot />
</article>
ハマりどころ・メモ
astro dev(開発サーバー)では検索は動かない。Pagefind のインデックスはbuild後にしか作られないので、開発中は/pagefind/pagefind-ui.jsなどが 404 になる。動作確認はnpm run build && npm run previewで行う。- 日本語は形態素解析(stemming)には非対応で、ビルド時に「ja は stemming 未対応」という注意が出る。検索自体は動くが、語幹をまたいだ一致はしない、という点は把握しておく。
- UI の見た目は Pagefind 側の CSS クラス(
.pagefind-ui__...)を上書きして調整できる。
サーバーレスのまま検索が付くので、静的ブログにはかなりおすすめです。
Pagefind, Astro