Astro製のサイトにPagefindを導入する

Pagefindとは?
Pagefindは、静的サイト向けの全文検索ライブラリ・UIライブラリです。
本サイトの記事検索機能はこのPagefindを用いて実装されています。
HugoやNext.js、SvelteKit、Astroなどの静的サイトジェネレータによってビルドされた後のHTMLに対してインデックスを作成し、検索をかけることができます。また同時にUIライブラリも提供されており、10行程度のコードを書き加えるだけで簡単にWebサイトへ検索機能が追加できます。
Astro製サイトに導入する
Pagefind公式が提供するライブラリを用いても良いですが、本記事(本サイト)ではastro-pagefind
を使用しています。このライブラリには、開発モード(npm run dev
した場合)でも検索機能を使用できる1、Astroの提供するViewTransitionsに対応している、などの利点があります。
Astro integration for Pagefind static site search. - shishkin/astro-pagefind
導入手順は以下の通り。
astro-pagefind
をインストール
pnpm add astro-pagefind
astro.config.mjs
に設定を追加
import { defineConfig } from 'astro/config';import pagefind from 'astro-pagefind';
export default defineConfig({ build: { format: 'file', }, integrations: [pagefind()],});
Search
コンポーネントを追加
---import Search from 'astro-pagefind/components/Search';---
<Search id="search" className="pagefind-ui" />
pnpm run dev
でローカルサーバを起動する
検索対象を指定する
data-pagefind-body
をつけると、その要素以下が検索の対象になります。本サイトでは、markdownの記事本文のみを検索対象に指定しています。
なお、検索から除外したい要素にはdata-pagedind-ignore
を追加します。
<section data-pagefind-body class="markdown-body"> <slot /></section>
メタデータを設定する
Pagefindでは、data-pagefind-meta
属性を指定することでメタデータを指定できます。このメタデータは検索結果と共に表示されます。
デフォルトでは、title
、image
、image_alt
の3種類を自動で抽出します。
image
メタデータは、ページの中で最初に登場する画像が設定され、検索結果画面でのサムネイルに使用されます。本サイトでは、image
メタデータをOG画像として使用している画像と同じものに設定するため、以下のような実装をしてメタデータを上書きしています。(メタデータがdata-pagefind-body
で指定した要素の内にある必要はないようです。)
<head> <meta property="og:image" data-pagefind-meta="image[content]" content={/* /path/to/ogp */} /></head>
また、data-pagefind-meta
属性にkey:value
構文で好きなメタデータを追加することができます。本サイトでは記事のカテゴリをメタデータとして追加しています。このほかメタデータとしては執筆日時・更新日時・執筆者・タグなどが考えられるでしょうか。
<a href="/categories/tech" data-pagefind-meta="category:Tech"> Tech</a>
Pagefind supports returning custom metadata alongside search results with the data-pagefind-meta attribute. Automatic metadata Pagefind will return some automa…
フィルターを設定する
Pagefindでは以下の画像のように、記事の検索結果についてさらにフィルターをかけることができます。
data-pagefind-filter
属性を用いることで、ページをフィルター名に関連付けることができ、要素の内容(以下の例ではeno1220
)がフィルタの値として扱われます。
<p> Author: <span data-pagefind-filter="author">eno1220</span></p>
本サイトでは以下のように記事につけられたタグに対してフィルター値を設定しています。
{post.data.tags.map((tag) => ( <a href={`/tags/${tag}`}> #<span data-pagefind-filter="tag">{tag}</span> </a>))}
To configure filters in Pagefind, pages are associated to filter keys and values using data attributes. Capturing a filter value from an element <h1>My Blog Po…
スタイルを変更する
初期時点では、pagefindの提供するデフォルトのスタイルが適用されています。CSSのカスタム変数を上書きするかオリジナルのCSSを当てることで、このスタイルを変更することができます。
Pagefind provides a Default UI component that supports searching, basic filtering, sub results, and metadata out of the box. Adding the Pagefind UI to a page P…
本サイトのカスタム変数は以下の通りです。参考までに…
.pagefind-ui { --pagefind-ui-text: $font-text; --pagefind-ui-background: #f5f5f5; --pagefind-ui-border: #ddd; --pagefind-ui-tag: #f5f5f5; --pagefind-ui-border-radius: 0.5rem; --pagefind-ui-border-width: 1px; --pagefind-ui-image-border-radius: 2px; --pagefind-ui-image-box-ratio: 2 / 1;}
おわりに
Pagefindを用いることで、非常に手軽にWebサイトにリッチな検索機能を追加することができました。
今回紹介した機能の他にも、検索結果の重み付けやソート等の便利な機能があるようなので、ぜひ試してみてください。
参考文献
Pagefind is a fully static search library that aims to perform well on large sites, while using as little of your users’ bandwidth as possible, and without hos…
Pagefind は、静的サイト向けの全文検索エンジンと UI ライブラリです。特定のフレームワークに依存しない JavaScript ライブラリとして実装されており、静的サイトジェネレーターで生成された HTML ファイルに対して検索機能を追加できます。
脚注
-
本来は、ビルドした後に
npx pagefind --site dist
でインデックスを作成してやる必要があり、開発モードでは検索機能が使用できない。 ↩