Webhookを使えばPagefind使えることに気が付いた

サイト内検索を実装したくて悩んだ記録です。初心者なので、用語の使い方や理解が間違っている可能性があります。

Pagefind

Pagefindは、静的サイト向けの検索ライブラリです。
https://pagefind.app/
調べてみるとAstroでの実装方法が書かれた記事も沢山ヒットするのでそれらを参考にして実装してみました。本当にありがたいです。

SSRのサイトではそのまま使えない

静的サイト向けのライブラリです。htmlを参照して検索のインデックスを作成するので、PagefindのCLIは、HTMLが事前に生成されていることを前提に動作します。
ページにアクセスされるときにhtmlを返すSSR(Server Side Rendering)サイトではもちろん使えない。
PagefindにNodeJS APIがあるので、これを利用できれば使えるのだと思うのですが、なんせ初心者で全くわからず。

記事の更新があったらすぐ反映しつつ、検索機能もつけたい。でも、難しいことはわからないし、他に簡単に実装できそうなライブラリも見つからず、悩んでいました。

Webhookで解決!

記事の更新ごとに手動でビルド&デプロイするしかないのか(SSG(Static Site Generation)として運用はできるが、その都度作業が発生する)と思っていました。ところが、Webhookを使えば自動化できることに気付きました。
Webhookを設定するとCMSで更新した時に自動的にデプロイしてくれます。つまり、更新があると静的なサイトをビルドしてデプロイしてくれます。なので、記事の更新→静的ページがビルド→生成されたhtmlを参照してPagefindがうまく動いてくれるわけです。

Webhookの設定はかなり簡単で、私はVercelとNewtを利用しているので、VercelでDeploy Hooksを作成してそれをNewtに設定するだけです。
Newt公式のチュートリアルもありました。
コンテンツの更新時にVercelでデプロイを行う

意気揚々と設定して更新してみたところ、エラーが出て焦りました。Astroの設定変更などをGithubにプッシュするのを忘れていたことが原因でした。WebhookはGithubの最新のコードでデプロイします。「まず基本がわかっていないとエラーになる」というあるあるをやってしまいました。
Githubに修正データをプッシュして再度Newtから更新してみると、問題なくデプロイされました。
ちなみに、Vercelでは生成されたhtmlが.vercel/output/staticに格納されるので、ビルドコマンドを以下のように修正する必要があります。

astro build && npx pagefind --site .vercel/output/static

おわりに

Pagefindは簡単に実装でき、挙動もとても良かったので、サイトに組み込めてよかったです。
当初は「CMSで更新した内容がすぐ反映されるならSSRの方が良い」と思い込んでいましたが、SSRにはデメリットもあることを知り、最終的にこの形に落ち着いて満足しています。
ただ、CMSの更新が頻繁にある場合、SSGではそのたびにビルドが走るため、ビルドに時間がかかったり、サーバーに負荷がかかったりすることがあります。とはいえ、現状のサイト規模では大きな問題にはならないと考えています。
もっと別の方法で検索機能を実装することにも挑戦してみたい——というか、できるようになりたい! と思いましたが、調べるほどにバックエンドの難しさを痛感します。それでも、自分のできる範囲で試行錯誤しながらチャレンジを続けていきたいです。

参考
静的サイト向けの全文検索エンジンと UI ライブラリの Pagefind