ENGINEERING ARTICLE
静的サイトにJavaScriptだけで検索機能を追加する方法|JSONを使った実装例
この記事は約3分で読めます
こんにちは、 @Manabu です。
静的サイトを運営していて記事数が増えてくると、目的の記事を探すための検索機能が欲しくなります。
ただ、検索のためだけにLambdaやデータベースを用意するのは、少し大きな構成になってしまいます。
今回は、ビルド時に検索用JSONを作り、ブラウザのJavaScriptだけでサイト内検索を行う方法について紹介します。
この記事は、以下のような方におすすめです。
こんな方におすすめ
- 静的サイトに検索機能を追加したい
- 検索用のサーバーやデータベースを用意したくない
- 数十件から数百件程度の記事を管理している
検索用JSONを生成する
サイトを生成するとき、公開記事から次の情報を抽出します。
- タイトル
- description
- URL
- 大分類
- カテゴリー
- タグ
- 投稿日と更新日
これをsearch-index.jsonとして出力します。
[
{
"title": "CloudFrontとS3の設定方法",
"description": "静的サイトの構成を紹介します。",
"url": "/aws/example/",
"category": "AWS",
"tags": ["CloudFront", "S3"]
}
]
検索フォームを作成する
検索ページへフォームと結果表示用の要素を用意します。
<form id="search-form">
<label for="search-input">記事を検索</label>
<input id="search-input" type="search" required>
<button type="submit">検索</button>
</form>
<p id="search-status"></p>
<div id="search-results"></div>
ブラウザで絞り込む
検索ページを開いたときにJSONを取得し、入力したキーワードがタイトル、説明、カテゴリー、タグに含まれる記事を表示します。
const form = document.querySelector('#search-form');
const input = document.querySelector('#search-input');
const status = document.querySelector('#search-status');
const results = document.querySelector('#search-results');
let posts = [];
fetch('/search-index.json')
.then(response => {
if (!response.ok) throw new Error('検索データを取得できませんでした。');
return response.json();
})
.then(data => {
posts = data;
})
.catch(error => {
status.textContent = error.message;
});
form.addEventListener('submit', event => {
event.preventDefault();
const keyword = input.value.trim().toLocaleLowerCase('ja-JP');
if (!keyword) return;
const matched = posts.filter(post => {
const target = [
post.title,
post.description,
post.category,
...(post.tags || []),
].join(' ').toLocaleLowerCase('ja-JP');
return target.includes(keyword);
});
status.textContent = `${matched.length}件の記事が見つかりました。`;
results.replaceChildren();
for (const post of matched) {
const link = document.createElement('a');
link.href = post.url;
link.textContent = post.title;
results.append(link);
}
});
検索結果の生成にinnerHTMLを使う場合は、JSON内の文字列をそのままHTMLとして挿入しないようにしてください。上記ではtextContentを使い、記事タイトルを文字列として追加しています。
この方法では、Lambda、API Gateway、データベースなどを用意する必要がありません。
URLのクエリから検索する
/search/?q=CloudFrontのようなURLに対応する場合は、URLSearchParamsから検索文字列を取得できます。
const params = new URLSearchParams(window.location.search);
const initialKeyword = params.get('q') || '';
input.value = initialKeyword;
タグのリンクから検索ページへ移動させる場合にも利用できます。
向いているサイト
- 数十件から数百件程度の記事サイト
- 更新時に静的ファイルを再生成できるサイト
- 複雑な全文検索を必要としないサイト
記事数や本文データが非常に多くなるとJSONのサイズも大きくなるため、その段階で外部検索サービスなどを検討します。
まとめ
今回は、検索用JSONとJavaScriptを使って、静的サイトに検索機能を追加する方法について紹介しました。
記事数がそれほど多くなければ、検索用のサーバーやデータベースを用意しなくても十分に対応できます。
静的サイトの構成を大きくせずに検索機能を追加したい方は、ぜひ参考にしてみてください。