faceted-navigation について
EC のデザイナーや開発者向けに、複数属性で商品一覧を絞り込み、状態を URL に反映する方法を案内するスキルです。Shopify、WooCommerce、BigCommerce、カスタムのヘッドレスストアを扱います。
主な機能
- 01複数の商品属性による絞り込み
- 02URL へのフィルター状態の同期
- 03モバイル向けフィルタードロワーの設定
- 04選択中フィルターとクリア操作の表示
活用シーン
- 01大規模カタログのカテゴリ一覧設計
- 02絞り込み結果の共有とブックマーク
- 03絞り込み時のブラウザー戻る操作の修正
- 04ヘッドレスストアでの URL 状態管理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill faceted-navigationインストール後、Claude Code で/faceted-navigationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
tile.jsonevals/facet-search-api-and-price-range-slider/criteria.jsontask.mdevals/facetpanel-accessibility-and-display/criteria.jsontask.mdevals/url-driven-filter-state-management/criteria.jsontask.md詳細
ファセットナビゲーション
概要
買い物客がサイズ、色、ブランド、価格帯、評価など複数の属性で同時に結果を絞り込める、フィルター可能な商品一覧ページ(PLP)を構築します。フィルターを共有、ブックマークでき、検索エンジンにクロールされるよう、URLも同期させます。優れたファセットナビゲーションは、SKUが50を超えるカタログで、測定可能なコンバージョン率の向上につながります。
このスキルを使用する場面
- 商品カタログが約50 SKUを超え、閲覧のみのナビゲーションで買い物客に不満が生じている場合
- カテゴリ/コレクション一覧ページを構築または再設計する場合
- SEOのためにクロール可能なファセットURL(例:
/shoes/running?color=black&size=10)が必要な場合 - 戻るボタンが正しく機能しない、従来のファセット実装を置き換える場合
- Algolia InstantSearchまたはElasticsearch上のカスタムファセットレイヤーを実装する場合
基本手順
ステップ1:マーチャントのプラットフォームを特定し、適切な方法を選ぶ
| プラットフォーム | 推奨方法 | 理由 |
|---|---|---|
| Shopify | ネイティブのコレクションフィルター(Online Store 2.0テーマ)を有効にし、Search & Discoveryアプリ(無料)をインストール | Dawn、SenseなどのOS2.0テーマは、Storefront APIによるネイティブのストアフロントフィルタリングに対応しています。Search & Discoveryを使うと、管理画面から同義語、ブースト、フィルターを設定できます |
| WooCommerce | FiboSearch(有料、年間$49)またはWooCommerce Product Filters(無料)プラグインをインストール | FiboSearchは価格スライダー、カラースウォッチ、在庫フィルターを備えたAJAX対応ファセットを追加します。無料のProduct Filtersプラグインでは、URL状態を含む基本的な属性フィルタリングが可能です |
| BigCommerce | Storefront → Search設定でFaceted Searchを有効にする(Cornerstoneおよびほとんどのテーマに組み込み済み) | BigCommerceのFaceted Searchはプラットフォームに標準搭載されています。管理画面でファセットとして表示する商品属性を設定でき、アプリは不要です |
| カスタム/ヘッドレス | Algolia InstantSearch、またはElasticsearchとURL状態管理を使って構築 | ファセットのロジック、選言的フィルタリング、件数の最新性を完全に制御できます。実装の詳細は以下を参照してください |
ステップ2:プラットフォームでファセットを設定する
Shopify
Search & Discoveryアプリを使用する(推奨):
- Shopify App StoreからSearch & Discoveryをインストールします(Shopify提供、無料)
- Apps → Search & Discovery → Filtersに移動します
- Add filterをクリックし、ファセットに使用する商品属性(例:色、サイズ、ブランド、価格)を選択します
- ドラッグしてフィルターの順序を変更します。使用頻度の高いものを先頭に配置します
- AvailabilityおよびPriceフィルターはデフォルトで表示するように設定し、バリアント固有のフィルターは折りたたんだ状態にします
- Online Store → Themes → Customizeで、テーマのコレクションテンプレートのサイドバーまたはドロワーにFiltersセクションが有効になっていることを確認します
テーマレベルのフィルター設定(Dawnテーマ):
- Online Store → Themes → Customizeに移動します
- コレクションページのテンプレートを開きます
- サイドバーでProduct gridをクリックし、Enable filteringとEnable sortingを有効にします
- Filter layoutをDrawer(モバイルに推奨)またはSidebar(デスクトップ)に設定します
Shopify Plusの場合: 新商品が追加されたときに、フィルター可能な属性で商品に自動的にタグを付けるには、Shopify Flowを使用します。
WooCommerce
オプション A:FiboSearch(高度な絞り込みにおすすめ):
- WordPress.org またはプラグインマーケットプレイスから FiboSearch – AJAX Search for WooCommerce をインストールします
- FiboSearch → Settings → Filters に移動し、フィルターバーを有効にします
- ファセットとして表示する属性を設定します:商品カテゴリー、価格帯、カスタム属性(例:色、サイズ)、在庫状況
- 属性ごとに Filter style をチェックボックスリストまたはカラースウォッチに設定します
- ページを再読み込みせずに結果が更新されるよう、AJAX filtering を有効にします
- Appearance → Widgets → Shop Sidebar から、または Gutenberg ブロック内にフィルターウィジェットを配置します
オプション B:WooCommerce Product Filters(無料):
- WordPress.org からインストールします
- Products → Filters → Add New Filter Group に移動します
- 次のフィルターを追加します:カテゴリー、属性(例:色、サイズ)、価格帯、商品タグ、在庫状況
- ショップページのサイドバーまたは商品グリッドの上に、フィルターショートコード
[woof]を配置します
URL の状態: どちらのプラグインも有効なフィルターをクエリパラメーターとして URL に書き込むため、結果を共有したり、ブックマークしたりできます。
BigCommerce
- BigCommerce のコントロールパネルで Storefront → Search に移動します
- Faceted Search の下で、スイッチを On に切り替えます
- ファセットとして表示する商品フィールドを選択します:Brand、Category、Price、Rating、および任意のカスタム Product Custom Fields
- 「さらに表示」リンクが表示されるまでに、ファセットごとに表示する値の最大数を設定します
- 価格ファセットでは、価格帯の区分(例:$0-$25、$25-$50、$50-$100)を設定します
- テーマ設定(Storefront → My Themes → Customize)で、フィルターサイドバーのレイアウトとモバイルドロワーの動作を設定します
注: Faceted Search を利用するには、Stencil ベースのテーマ(Cornerstone および最新の BigCommerce テーマのほとんど)が必要です。旧式の Blueprint テーマは対応していません。
カスタム/ヘッドレス
ヘッドレスストアフロントでは、検索バックエンドを使って URL の状態に基づく絞り込みを実装します。
URL 状態のスキーマ — 有効なフィルターはすべてクエリパラメーターに格納されます:
/products/shoes?brand=Nike&brand=Adidas&color=black&size=10&price_min=50&price_max=150&sort=price_asc&page=1
URL 状態の解析と構築:
// lib/facetUrl.js
export function parseFiltersFromUrl(searchParams) {
const filters = {};
for (const [key, value] of searchParams.entries()) {
if (['sort', 'page', 'q'].includes(key)) continue;
if (!filters[key]) filters[key] = [];
filters[key].push(value);
}
return filters;
}
export function buildUrlFromFilters(filters, sort, page) {
const params = new URLSearchParams();
for (const [facetKey, values] of Object.entries(filters)) {
values.forEach(v => params.append(facetKey, v));
}
if (sort) params.set('sort', sort);
if (page && page > 1) params.set('page', String(page));
return `?${params.toString()}`;
}
分離型ファセットを使った Algolia クエリ(1 つのファセット内は OR、ファセット間は AND):
const result = await index.search(query ?? '', {
facets: ['brand', 'color', 'size', 'price_range'],
// facetFilters = OR within a facet group, AND between groups
facetFilters: Object.entries(filters)
.filter(([k]) => !['price_min', 'price_max'].includes(k))
.map(([key, values]) => values.map(v => `${key}:${v}`)),
filters: [
filters.price_min ? `price >= ${filters.price_min[0]}` : null,
filters.price_max ? `price <= ${filters.price_max[0]}` : null,
].filter(Boolean).join(' AND '),
hitsPerPage: 24,
page: page - 1,
});
フィルターを切り替えて URL 状態をプッシュ:
function toggleFilter(facetKey, value, currentFilters, sort) {
const current = currentFilters[facetKey] ?? [];
const next = current.includes(value)
? current.filter(v => v !== value)
: [...current, value];
const updated = next.length
? { ...currentFilters, [facetKey]: next }
: (({ [facetKey]: _, ...rest }) => rest)(currentFilters);
// Push new URL — each filter change gets its own history entry for back-button support
window.history.pushState({}, '', buildUrlFromFilters(updated, sort, 1));
return updated;
}
ステップ 3:モバイルでのフィルター操作を設定する
モバイルでは、フィルターパネルは「Filter」ボタンで開くボトムドロワーとして表示します。画面の半分を占める、常時表示のサイドバーにはしないでください。
- Shopify(Dawn): Theme Customizer で Filter layout を Drawer に設定します。モバイルではすでにこれがデフォルトです
- WooCommerce(FiboSearch): FiboSearch の設定で Mobile filter button を有効にします。プラグインによって折りたたみ可能なフィルターパネルが追加されます
- BigCommerce: テーマ設定で Filter drawer on mobile を有効にします。Cornerstone はこれを標準で処理します
- カスタム: 画面幅が 640px 未満の場合は
position: fixed; bottom: 0のドロワーにフィルターを表示し、有効なフィルター数を N として「Filter (N)」ボタンで開きます
ステップ 4:有効なフィルターのピルとクリア操作を追加する
すべてのプラットフォームで、適用されたフィルターを商品グリッドの上に削除可能なピルとして表示します。
- Shopify(Search & Discovery): 有効なフィルターのピルは OS2.0 のフィルターセクションに組み込まれています。Theme Customizer で有効にします
- WooCommerce: FiboSearch はデフォルトで有効なフィルタータグを表示します。別に表示するには
[woof_active_filters]ショートコードを追加します - BigCommerce: Cornerstone は有効な絞り込み条件を自動的に表示します。見当たらない場合は、テンプレートに Active Facets セクションを追加します
- カスタム: URL のフィルター状態からピルを表示します。各ピルには × ボタンがあり、これを押すと
toggleFilterを呼び出してフィルターを削除します
ベストプラクティス
- フィルターの状態を URL に含める — アクティブなフィルターを JavaScript の状態だけに保存しないでください。共有、ブックマーク、戻るボタンの動作において、URL が信頼できる情報源になります
- 同じグループ内では選択したファセットを OR 条件にする — Nike と Adidas の両方を選択した場合、空の検索結果ではなく、どちらかのブランドの商品を表示してください
- すべてのレスポンスでファセットの件数を返す — 件数にはカタログ全体ではなく、現在のフィルター条件を反映してください
- ファセットの表示は上位 10 件までに制限する — モバイルユーザーの画面が情報過多にならないよう、「さらに表示」の切り替えを用意してください
- 価格範囲スライダーの更新をデバウンスする — 毎回の目盛り移動時ではなく、マウスボタンを離したとき、またはタッチを終了したときにのみ範囲を確定してください
- 「すべてクリア」を用意する — フィルターが 1 つでも有効な場合は、常に表示してください
よくある問題
| 問題 | 解決策 |
|---|---|
| 戻るボタンを押すと、最後のフィルターが削除されずにページが再読み込みされる | フィルターを変更するたびに history.replaceState ではなく history.pushState を使用してください |
| 最初のフィルター選択後、ファセットの件数が更新されない | Algolia のディスジャンクティブ・ファセット、または Search & Discovery に組み込まれた件数更新機能を使って、フィルターを変更するたびにファセットの件数を再取得してください |
| モバイルでフィルターパネルがコンテンツに重なる | モバイルでは「フィルター」ボタンから開くドロワーまたはモーダルを使用してください。画面幅が 640px 未満の場合は、サイドバーを表示しないでください |
| ファセット URL によって SEO 上の重複コンテンツが発生する | 主要でないファセットの組み合わせには rel="noindex" または canonical タグを追加してください。これは Shopify の Search & Discovery の SEO 設定で構成できます |
| 価格範囲スライダーのつまみが重なる | 変更のたびに、最大値のつまみの最小値を現在の最小値+ステップに制限し、最小値のつまみの最大値を現在の最大値-ステップに制限してください |
関連スキル
- @search-autocomplete
- @product-categorization
- @accessibility-commerce
- @product-page-design