Pagefind を使ってみました。
Pagefind はフロントエンドだけで検索の機能を処理することができるので、静的サイトで使うと便利です。
自分の場合、 Astro 製のブログに Pagefind を用いて、検索のページを作成しました。
目次
- Pagefind をインストールする
- Pagefind でインデックスのファイルを生成する
- Astro でビルドをして Pagefind でインデックスのファイルを生成する
- Pagefind で生成されるファイルについて
- Astro で Pagefind の UI を表示する
- 日本語で検索できるようにする
- 日本語で検索する際に、全角空白も検索クエリに含まれてしまう
- Pagefind の UI のフォントを変更する
- 検索結果の表示件数を変更する
- サブリザルトを有効化する
- 記事のページだけをインデックスさせる
- おわりに
- 参考記事
Pagefind をインストールする
Pagefind を npm などのコマンドでインストールします。
$ npm install pagefind
Pagefind でインデックスのファイルを生成する
Pagefind のコマンドを実行して、インデックスのファイルを生成します。
--site
コマンドライン引数には、ビルドした静的サイトのファイルが格納されているディレクトリのパスを指定します。
Astro で静的サイトをビルドした場合、デフォルトでは dist
ディレクトリにファイルが出力されますので、 --site
コマンドライン引数に dist
ディレクトリを指定してます。
$ npx pagefind --site "dist"
Running Pagefind v1.1.0 (Extended)
Running from: [REDACTED]
Source: "dist"
Output: "dist\\pagefind"
[Walking source directory]
Found 40 files matching **/*.{html}
[Parsing files]
Did not find a data-pagefind-body element on the site.
↳ Indexing all <body> elements on the site.
[Reading languages]
Discovered 1 language: en
[Building search indexes]
Total:
Indexed 1 language
Indexed 40 pages
Indexed 1364 words
Indexed 0 filters
Indexed 0 sorts
Finished in 0.328 seconds
Astro でビルドをして Pagefind でインデックスのファイルを生成する
Astro で静的サイトをビルドして、 HTML などのファイルを生成します。
それから HTML などの生成されたファイルを Pagefind で解析して、インデックスのファイルを生成します。
最後に Astro のプレビューのコマンドを実行して、サイトの確認をします。
$ npx astro build
$ npx pagefind --site "dist"
$ npx astro preview
Pagefind で生成されるファイルについて
Pagefind でインデックスのファイルを生成した場合、下記のようにファイルが生成されます。
dist
ディレクトリ直下に pagefind
というディレクトリが作成されます。
fragment
や index
のディレクトリには、たくさんのファイルが生成されました。
Pagefind の UI で使用される pagefind-ui.js
などのファイルも生成されました。
$ tree ./dist/pagefind
./dist/pagefind
|-- filter
| `-- ja_ccb734b.pf_filter
|-- fragment
| |-- ...
| `-- ja_ffed1c7.pf_fragment
|-- index
| |-- ...
| `-- ja_f6bb4db.pf_index
|-- pagefind-entry.json
|-- pagefind-highlight.js
|-- pagefind-modular-ui.css
|-- pagefind-modular-ui.js
|-- pagefind-ui.css
|-- pagefind-ui.js
|-- pagefind.ja_3e1987ffbf.pf_meta
|-- pagefind.js
`-- wasm.unknown.pagefind
3 directories, 174 files
Astro で Pagefind の UI を表示する
Astro で Pagefind の UI を表示します。
src/pages
ディレクトリ内に search.astro
などの名前で適当にファイルを作成します。
それから下記のようにコードを記述します。
<link rel="stylesheet" href="/pagefind/pagefind-ui.css" />
<script is:inline src="/pagefind/pagefind-ui.js"></script>
<script is:inline>
document.addEventListener("DOMContentLoaded", () => {
new PagefindUI({ element: "#search" });
});
</script>
<div id="search"></div>
Astro を使用しておりますので、 script 要素には is:inline
属性の記述を追加しております。
is:inline
属性の記述が不要な場合には削除してください。
ファイルを作成して、 Pagefind の UI を表示するコードを記述したら、再度 Astro でビルドして、 Pagefind でインデックスのファイルを生成します。
それから Astro のプレビューのコマンドを実行し、 Pagefind の UI の挙動を確認します。
日本語で検索できるようにする
最初は html 要素の lang 属性に en を指定していたため、日本語では検索できませんでした。
そこで html 要素の lang 属性に ja を指定したところ、日本語で検索できるようになりました。
<html lang="ja">
日本語で検索する際に、全角空白も検索クエリに含まれてしまう
Pagefind で検索する際に、区切り文字として全角空白を入力した場合、その全角空白では区切られずに、一つの単語として処理されてしまいます。
検索時に期待されている処理としては、全角空白も区切り文字として認識されるような処理だと思います。
一応、半角空白で単語を区切れば、別々の単語として処理されます。
なので、ユーザの入力があった場合に、全角空白を半角空白に置換するような処理を挟めばいいと思います。
Pagefind の UI のフォントを変更する
Pagefind の UI のスタイルは変更することができます。
CSS の変数を使用することで、 Pagefind の UI の色やフォントなどを変更することができます。
Using the Default UI | Pagefind — Static low-bandwidth search at scale
Pagefind で生成された CSS のファイルには :root セレクタに CSS の変数が定義されていました。
:root {
--pagefind-ui-scale: .8;
--pagefind-ui-primary: #393939;
--pagefind-ui-text: #393939;
--pagefind-ui-background: #ffffff;
--pagefind-ui-border: #eeeeee;
--pagefind-ui-tag: #eeeeee;
--pagefind-ui-border-width: 2px;
--pagefind-ui-border-radius: 8px;
--pagefind-ui-image-border-radius: 8px;
--pagefind-ui-image-box-ratio: 3 / 2;
--pagefind-ui-font: system, -apple-system, "BlinkMacSystemFont", ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif;
}
下記のように記述することで Pagefind の UI のフォントを変更することができます。
下記の記述でも is:inline
属性を記述していますので、不要な場合には削除してください。
<style is:inline>
:root {
--pagefind-ui-font: "BIZ UDPGothic", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
</style>
検索結果の表示件数を変更する
pageSize
オプションを変更すると、検索結果の表示件数を変更することができます。
デフォルトでは表示件数は 5 件となっていますが、 10 件に変更しました。
<script is:inline>
document.addEventListener("DOMContentLoaded", () => {
new PagefindUI({
element: "#search",
pageSize: 10,
});
});
</script>
サブリザルトを有効化する
サブリザルトを有効化すると、検索結果に 3 件までの見出しが表示されるようになります。
デフォルトではサブリザルトは無効化されております。
Showing multiple results per page | Pagefind — Static low-bandwidth search at scale
<script is:inline>
document.addEventListener("DOMContentLoaded", () => {
new PagefindUI({
element: "#search",
showSubResults: true
});
});
</script>
記事のページだけをインデックスさせる
Pagefind で記事のページだけをインデックスさせる場合、 data-pagefind-body
属性や data-pagefind-ignore
属性を特定の要素に記述します。
そうすることで、タグのページなどをインデックスから除外することができます。
Configuring what content is indexed | Pagefind — Static low-bandwidth search at scale
記事のページのインデックスさせたい箇所に data-pagefind-body
属性を記述します。
下記のように記述することで、記事のタイトルや本文などだけをインデックスに含めることができます。
data-pagefind-body
記述している要素の子要素で除外したい箇所がある場合、その要素に data-pagefind-ignore
属性を記述します。
<main data-pagefind-body>
<h1>タイトル</h1>
<article>
<p>本文</p>
</article>
<ul data-pagefind-ignore="all">
<li>
<span>タグ1<span>
</li>
<li>
<span>タグ2<span>
</li>
<li>
<span>タグ3<span>
</li>
</ul>
</main>
data-pagefind-body
属性を記述したら、 Pagefind のインデックスを生成するコマンドを実行します。
そうすると、下記のように data-pagefind-body
属性が記述された要素が見つかったとコンソールに表示されます。
[Parsing files]
Found a data-pagefind-body element on the site.
↳ Ignoring pages without this tag.
data-pagefind-body
属性を記述した場合、 data-pagefind-body
属性を記述していない他のページはインデックスされなくなります。
記事のページだけに data-pagefind-body
属性を記述してしまえば、タグのページなどはインデックスに含まれなくなります。
Removing pages from Pagefind’s index
Once a data-pagefind-body attribute exists on any page of your site, any pages without this attribute will not be indexed.
As such, the best way to remove pages is by adding data-pagefind-body to the pages you would like to index.
おわりに
Pagefind を使ってみました。
Astro などで静的サイトをビルドする場合に、 Pagefind を使用すれば、かんたんに検索のページを作成することができます。