技術 約2分で読めます

Astro静的サイトにPagefindで全文検索を追加する

静的サイトの弱点の一つが検索機能。サーバーサイドがないので、外部サービスを使うか自前で何とかするしかない。

今回、このブログにPagefindを導入したので、その手順をメモ。

Pagefindとは

Pagefindは静的サイト向けの全文検索ライブラリ。

特徴:

  • ビルド時にHTMLをクロールしてインデックス生成
  • インデックスは細かいチャンクに分割(必要な部分だけfetch)
  • WebAssemblyで高速検索
  • 日本語対応
  • 外部サービス不要

1000ページあっても初期ロードは数十KB程度で済む。

インストール

Astroの場合、astro-pagefindというインテグレーションがある。

pnpm add astro-pagefind @pagefind/default-ui

astro.config.mjsに追加:

import pagefind from 'astro-pagefind';

export default defineConfig({
  integrations: [pagefind()],
  // ...
});

検索ページの作成

---
import BaseLayout from '@/layouts/BaseLayout.astro';
---

<BaseLayout title="検索" description="記事を検索">
  <main>
    <h1>検索</h1>
    <div id="search"></div>
  </main>
</BaseLayout>

<script>
  import { PagefindUI } from '@pagefind/default-ui';
  import '@pagefind/default-ui/css/ui.css';

  new PagefindUI({
    element: '#search',
    showSubResults: true,
    translations: {
      placeholder: '記事を検索...',
      zero_results: '「[SEARCH_TERM]」に一致する記事が見つかりませんでした',
    },
  });
</script>

スタイルのカスタマイズ

PagefindのUIはCSS変数でカスタマイズできる。

<style is:global>
  :root {
    --pagefind-ui-scale: 1;
    --pagefind-ui-primary: hsl(var(--primary));
    --pagefind-ui-text: hsl(var(--foreground));
    --pagefind-ui-background: hsl(var(--background));
    --pagefind-ui-border: hsl(var(--border));
    --pagefind-ui-tag: hsl(var(--secondary));
    --pagefind-ui-border-width: 1px;
    --pagefind-ui-border-radius: 0.5rem;
    --pagefind-ui-font: inherit;
  }
</style>

既存のデザインシステムの変数をそのまま使える。

注意点

開発サーバーでは動かない

pnpm devでは検索が動かない。Pagefindのインデックスはpnpm buildで生成されるため。

確認はpnpm preview(ビルド後のプレビュー)で行う。

ビルド時間への影響

Pagefindのインデックス生成は軽い。数百ページでも数秒程度。Vercelの無料プランでも問題ない。

このブログ(約80ページ)で0.4秒程度だった。

まとめ

  • astro-pagefind@pagefind/default-uiをインストール
  • 検索ページを作成してPagefindUIを初期化
  • スタイルはCSS変数でカスタマイズ
  • 開発時はpnpm previewで確認

外部サービスなしで全文検索が実現できるのは便利。