2024-02-25

Pagefindを使って検索機能を実装する
Pagefindで検索機能を実装
参考サイト
Pagefind公式サイト
https://pagefind.app/docs/resources/#using-pagefind-with-a-specific-ssg
Astro-pagefind
https://github.com/shishkin/astro-pagefind?tab=readme-ov-file
Astro build configuration
https://docs.astro.build/en/reference/configuration-reference/#buildformat
Searchの設定オプション
選定理由
- 導入が簡単
- 将来的に利用しようと思っているTransitions APIに対応している
Bunへ移行
現在開発しているものはBunに移行しているのでこちらも移行。
rm -rf node_modules/ package-lock.json
bun i
実装
bun add astro-pagefind
astro.config.mjs
integrations: [pagefind()],
ビルド
Running Pagefind v1.0.4 (Extended)
Running from:
Source:
Output:
[Walking source directory]
Found files matching **/*.{html}
[Parsing files]
Indexing all <body> elements on the site.
[Reading languages]
Discovered language:
[Building search indexes]
Total:
のようにインデックスされたものがアウトプットされ、検索することが可能になる。
コンポーネントの配置
ヘッダー部分はシンプルにしたいと思っていたので,そこには配置したくなかった。
そこでビルド時にインデックスを既に作成しているため高速に動作する特性から考えて,ヘッダーの真下に配置することでユーザ側からしても知りたい情報が含まれているかどうかを瞬時に検索して結果を得ることができ,記事があれば遷移することができるし,なければ実際に最新の記事から楽しむことができるという観点でもとても利用しやすいと考えた。
またサイトを訪れるときはなんらかの検索ワードを持っていることが多いと思うので,関連の情報を知りたいために訪れた人にとってはより利便性に優れたものになると思った。
ダークモード
おそらくデフォルトではダークモードをサポートしていないように思ったので,自前実装。
ライトモードではデフォルトをそのまま利用。
FindSearch.astro
<style is:global>
@media (prefers-color-scheme: dark) {
.pagefind-ui__search-input.svelte-e9gkc3 {
background-color: #121314;
border: none;
color: white;
}
.pagefind-ui__search-clear.svelte-e9gkc3 {
background-color: #121314;
border: none;
color: white;
}
.pagefind-ui--reset mark {
background-color: #ffff99;
color: #4a4949;
}
.pagefind-ui__result-title.svelte-j9e30
.pagefind-ui__result-link.svelte-j9e30 {
color: white;
}
.pagefind-ui__message.svelte-e9gkc3 {
color: #d3d3d3;
}
.pagefind-ui__result-excerpt.svelte-j9e30.svelte-j9e30 {
color: #d3d3d3;
}
}
</style>
ビルド時の注意点
ドキュメント通りの,設定を行うと
build: {
format: "file",
},
という設定があるが自分の環境ではこれを利用した場合,検索結果以外のパスに拡張子が含まれなくなってしまい画面遷移ができなくなってしまったのでデフォルトのビルドを利用した。
Astroのビルドフォーマットについては参考リンクを参照。
Searcnコンポーネントのオプション
内部的にはデフォルトのPagefindを利用しているので,参考リンクの提供APIから簡単に制御できる。
FindSearch.astro
<Search
id="search"
uiOptions={{ showImages: false, pageSize: 3, excerptLength: 15 }}
/>