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を使用すれば、かんたんに検索のページを作成することができます。