blog.eno1220.dev

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

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に対応している、などの利点があります。

導入手順は以下の通り。

  1. astro-pagefindをインストール
Terminal window
pnpm add astro-pagefind
  1. astro.config.mjsに設定を追加
astro.config.mjs
import { defineConfig } from 'astro/config';
import pagefind from 'astro-pagefind';
export default defineConfig({
build: {
format: 'file',
},
integrations: [pagefind()],
});
  1. Searchコンポーネントを追加
---
import Search from 'astro-pagefind/components/Search';
---
<Search id="search" className="pagefind-ui" />
  1. pnpm run devでローカルサーバを起動する

検索対象を指定する

data-pagefind-bodyをつけると、その要素以下が検索の対象になります。本サイトでは、markdownの記事本文のみを検索対象に指定しています。
なお、検索から除外したい要素にはdata-pagedind-ignoreを追加します。

<section data-pagefind-body class="markdown-body">
<slot />
</section>

メタデータを設定する

Pagefindでは、data-pagefind-meta属性を指定することでメタデータを指定できます。このメタデータは検索結果と共に表示されます。

デフォルトでは、titleimageimage_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では以下の画像のように、記事の検索結果についてさらにフィルターをかけることができます。

フィルタ機能のスクリーンショット

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>
))
}

スタイルを変更する

初期時点では、pagefindの提供するデフォルトのスタイルが適用されています。CSSのカスタム変数を上書きするかオリジナルのCSSを当てることで、このスタイルを変更することができます。

本サイトのカスタム変数は以下の通りです。参考までに…

.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サイトにリッチな検索機能を追加することができました。
今回紹介した機能の他にも、検索結果の重み付けやソート等の便利な機能があるようなので、ぜひ試してみてください。

参考文献

脚注

  1. 本来は、ビルドした後にnpx pagefind --site distでインデックスを作成してやる必要があり、開発モードでは検索機能が使用できない。

記事の要約を生成(beta)

※要約はGemini Nanoによって生成されたものです。内容の正確性を保証するものではありません。

Chrome組み込みのLLM「Gemini Nano」を利用して記事の要約を生成します。 生成には数十秒程度かかることがあります。 デバイスのCPUやメモリ、バッテリーの使用率が上昇することがありますのでご注意ください。

blog.eno1220.devのアイコン

eno1220

Webフロントエンドや低レイヤー(OSや言語処理系等)が好きな18歳です。
42Tokyoでプログラミングの勉強をしています。