ドキュメント検索にシノニム・ユースケースキーワードを追加し、コンポーネントの発見性を向上

shoelace-style/webawesome

WebAwesomeのサイト内検索に synonyms(同義語)と use-cases(ユースケース)フロントマターフィールドを追加し、ブーストウェイト付きでMiniSearchインデックスに組み込んだ。これにより「modal」でDialogが、「sidebar」でDrawerが見つかるなど、正式名称を知らないユーザーでも目的のコンポーネントにたどり着けるようになった。

背景

WebAwesomeのコンポーネントは独自の命名規則を持つが、開発者が直感的に思い浮かべる名称と一致しないことがある。たとえば、モーダルウィンドウを探したいユーザーが「modal」と入力しても、コンポーネント名が「Dialog」であるため検索結果に表示されなかった。

PRに添付された変更前後の比較表が問題の規模を示している:

クエリ 変更前 変更後
sidebar 結果なし Drawer
accordion Format Date Details
lightbox 結果なし Dialog
combobox Popup Select
offcanvas 結果なし Drawer
loader Installation Spinner

こうした検索ミスマッチは、コンポーネントの発見性を損ない、ユーザー体験に直結する問題だった。

技術的な変更

フロントマターへのキーワード定義

89のドキュメントファイルに、2つの新しいフロントマターフィールドが追加された。synonyms はコンポーネントの別名、use-cases はそのコンポーネントを使う動機・文脈を記述する。Dialogコンポーネントを例にとると、以下のように定義される:

synonyms:
  - modal
  - popup
  - lightbox
  - overlay
  - modal dialog
use-cases:
  - confirmation dialog
  - alert dialog
  - prompt
  - login modal
  - cookie consent

Drawerには sidebaroffcanvastraysheet といった同義語が、Detailsには accordioncollapsibledisclosure が割り当てられている。

検索プラグインの改修(_plugins/search.js

インクリメンタルビルドのキャッシュ機構に変更が加わった。従来、pagesToIndex マップは true(未処理)またはページデータそのもの(処理済み)を格納するシンプルな構造だったが、新フィールドを保持するためにオブジェクト形式に変更されている。

変更前:

// プリプロセッサ
pagesToIndex.set(data.page.inputPath, true);

// トランスフォーム(キャッシュ利用判定)
if (pagesToIndex.get(key) === true) {
  pagesToIndex.set(key, value);
}

変更後:

// プリプロセッサ: フロントマターデータへのアクセス権があるここでキーワードをキャッシュ
pagesToIndex.set(data.page.inputPath, {
  pending: true,
  synonyms: data.synonyms || [],
  useCases: data['use-cases'] || [],
});

// トランスフォーム(キャッシュ利用判定)
const current = pagesToIndex.get(key);
if (current?.pending) {
  pagesToIndex.set(key, { ...value, synonyms: current.synonyms, useCases: current.useCases });
}

Eleventyのビルドパイプラインでは、プリプロセッサフックはフロントマターデータにアクセスできるが、トランスフォームフックはアクセスできない。そのため、プリプロセッサ段階でキーワードを pagesToIndex にキャッシュし、トランスフォームで HTML コンテンツとマージする2段階処理が導入された。インクリメンタルビルド時に全ファイルがトランスフォームを通過しない制約を回避するため、pending フラグによって「まだトランスフォーム未処理のページ」を識別し、キャッシュ済みデータにキーワードを上書きマージする仕組みになっている。

検索フロントエンドの改修(assets/scripts/search.js

MiniSearchの設定に2フィールドを追加し、ブーストウェイトを設定している:

変更前:

const searchIndex = MiniSearch.loadJSON(JSON.stringify(searchData.searchIndex), {
  fields: ['t', 'h', 'c'],
});
// ...
boost: { t: 20, h: 10 }

変更後:

const searchIndex = MiniSearch.loadJSON(JSON.stringify(searchData.searchIndex), {
  fields: ['t', 'h', 's', 'u', 'c'],
});
// ...
boost: { t: 20, s: 14, h: 10, u: 6, c: 1 }

短縮フィールド名は t(title)、h(headings)、s(synonyms)、u(use-cases)、c(content)に対応する。

設計判断

ブーストウェイトの階層化が本PRの設計の核心である。5段階のウェイト(20→14→10→6→1)を設定することで、既存の検索ランキングを壊さずに新しいキーワードを適切な優先度で挿入している。

synonymsとuse-casesを別フィールドとして扱う点も重要な設計判断だ。synonymsのブースト14は「タイトル直接一致(20)」よりは低いが「見出し一致(10)」より高い位置に置かれ、「この語はまさにこのコンポーネントの別名である」という強い対応関係を表現する。一方、use-casesのブースト6は「このコンポーネントで解決できる問題」という間接的な関連性を反映し、本文コンテンツ(1)よりは高く評価される。この分離により、「modal」という検索ではDialogが上位に来るが、「cookie consent」という検索でも適切にDialogが見つかるという多層的な発見性が実現されている。

キーワードをフロントマターに定義する方式は、コンポーネントの担当者がドキュメントと一体として管理できるという利点がある。検索インデックスの設定ファイルと切り離すことで、新しいコンポーネントを追加する際も同じフローでキーワードを定義できる。

まとめ

本PRは検索エンジンの精度向上ではなく、「コンポーネントの意味的な発見性」をドキュメントのフロントマターとして定義可能にした変更である。プリプロセッサ・トランスフォームの2段階キャッシュ機構によりEleventyのインクリメンタルビルド制約を回避しつつ、MiniSearchのブーストウェイト階層化によって既存の検索体験を壊さずに新次元のキーワードマッチングを追加している。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
04c8f6a0

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)という理想的な3部構成が明確に適用されています。各セクションの役割も明確で、非常に分かりやすいです。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```言語:ファイルパス)とGitHubのPRリンク記法([#番号](URL))が、ガイドライン通りに正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

EleventyのビルドフックやMiniSearchのブースト設定など、専門知識を持つエンジニアを対象とした内容になっており、過度な初心者向けの説明がなく適切です。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、かつ各段落がトピックセンテンスで始まるため、非常に構造的で読みやすいです。1段落1トピックの原則も守られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のすべてのコードブロック(変更前・変更後)が、提供されたDiff情報と完全に一致しています。ファイルパスの指定も正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「フロントマター」「プリプロセッサフック」「トランスフォームフック」「インクリメンタルビルド」「ブーストウェイト」など、技術用語が正確かつ文脈に即して使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

Eleventyのビルドパイプラインにおける制約と、それを回避するための2段階キャッシュ機構に関する説明は、Diffの内容とPRのコメントによって裏付けられており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

「89のドキュメントファイルを変更」という具体的な数値や、Before/Afterの比較表、ブーストウェイトの設計意図など、記事内のすべての主張がPRのDescriptionやDiffで裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2289)、ブーストウェイト(20, 14, 10, 6, 1)、変更ファイル数(89)など、記事に含まれるすべての数値・固有名詞が正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトル「ドキュメント検索にシノニム・ユースケースキーワードを追加し、コンポーネントの発見性を向上」は、PRの主題と目的を的確に要約しており、内容との整合性が高いです。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事の内容はすべて提供されたPR情報に基づいており、バージョンサポート状況やリリース日程など、PRに記載のない外部知識の追加はありません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「〜ようになった」といった表現は、PRの「now finds」という記述と一致しており、時間表現の歪曲はありません。