このブログのサイト内検索は、どう動いているのか
このブログでは、画面上部の検索ボタンから、記事の中に書いた言葉を探せる。Macでは⌘ + Kでも開く。
使っているのはPagefindだ。今回は既存の実装を読み、どこから検索用のデータが作られているのか、実際に日本語で何が見つかるのかを確認した。

画像:このサイトの検索画面。11本の記事がある本番ビルドのプレビューで確認。
検索用のデータは、ビルド後に作る
このサイトのビルド処理は、次の順番になっている。
astro build && pagefind --site distまずAstroが記事や固定ページのHTMLをdistへ出力する。そのあとPagefindがHTMLを読み、検索に必要なデータをdist/pagefindへ作る。
記事のMDX
→ AstroでHTMLを生成
→ Pagefindで検索用データを生成
→ HTMLと検索用データを一緒に配信検索するときは、ブラウザが必要な検索データを読み込む。この構成では、検索のための専用APIやDBを自分で運用していない。Pagefindの公式説明も、静的なHTMLを索引化し、サイトと一緒に配信する仕組みとして紹介している。
ただし、記事を書き換えただけでは検索データは更新されない。更新したHTMLを作り、そのあとに索引を作り直すところまでが一組になる。
何を検索対象にするか
本文を囲むMarkdownBody.astroには、次の属性がある。
<div class="stack" data-pagefind-body>
<slot />
</div>このサイトでは、これを検索対象の本文としている。検索結果に使うタイトルは、共通のメタデータ部品にあるdata-pagefind-meta="title"から渡している。
全ページのナビゲーションやフッターを本文と同じように拾うより、探したい内容へ範囲を絞れる。
ただし、この部品は記事専用ではない。Aboutにも使われている。そのため、このブログの検索結果には記事以外のページも出る。ページを記事か固定ページかで分けるより、どの部品に検索対象の印を付けているかを見ると、今の挙動を説明しやすい。
表示は既存のUIを使っている
検索結果の表示には、@pagefind/default-uiを使っている。このサイトでの主な設定は、次のとおりだ。
| 設定 | 値 | 表示への影響 |
|---|---|---|
element | #search | 検索画面を置く場所 |
pageSize | 15 | 結果の表示単位 |
showImages | false | 結果に画像を出さない |
placeholder | キーワードで検索する | 入力欄の案内 |
clear_search | クリア | 入力を消すボタン |
画像は出さず、タイトルと本文の抜粋から記事を選べる形になっている。見た目の色はサイトの背景色や文字色に合わせている。
日本語で試した
確認には、開発サーバーではなく、本番向けにビルドしたサイトのプレビューを使った。Pagefindが読むのはビルド後のHTMLなので、普段のastro devだけでは同じ条件にならない。
11本の記事が公開されている時点のデータで、「アルセウス」と検索した。
結果には、「誰よりも先に、アルセウスを捕まえたかった」とAboutの2ページが出た。Aboutにもその思い出を書いているので、本文から見つかっていることが分かる。結果の抜粋でも、検索した言葉が強調されていた。
技術用語として「トランザクション」も検索し、グリッチハンターのDB設計記事が出ることを確認した。
この結果だけで、日本語の言い換えや誤字にすべて対応できるとは言えない。まず、実際に記事で使っている言葉から、その記事へたどれることを確認した。
日本語の警告は、意味を確認する
ビルドログには、日本語のstemmingに対応していないという案内が出ていた。stemmingは、語の変化を共通の形へ寄せる処理のことだ。
Pagefindの多言語検索の説明では、日本語などに対して、空白のない文章を単語へ分ける処理とstemmingを分けて説明している。今回使っているExtended版では、日本語の単語分割が扱われる。
「日本語」という言葉を含む警告が出たから検索できない、と判断せず、何に対応していないのかを読み、実際の語で確かめる必要があった。
公開後の確認にも、検索を入れる
今後記事を増やしたときには、本文に特徴的な言葉を一つ選んで検索する。その記事が出るか、抜粋が読めるか、リンクから正しいページへ移動できるかを確認したい。
下書きは本番のHTMLから除外しているので、本番ビルドから作る検索用データにも含めない。この扱いは下書きの公開制御の記事にまとめた。
検索ボックスが表示されることと、新しい記事が見つかることは、確認する場所が違う。HTMLを作ったあとに検索データも更新する。今の構成では、その順番を守ることが大事になる。
この記事は、このサイトにあるPagefindの実装をCodexと読み返した記録です。Pagefind 1.5.2、@pagefind/default-uiを使う構成で確認しました。導入当初の経緯を再現した記事ではありません。