skills/storefront-ui/faceted-navigation/SKILL.md
Let shoppers filter products by multiple attributes simultaneously with URL-shareable filter state, instant results, and mobile-friendly controls
npx skillsauth add finsilabs/awesome-ecommerce-skills faceted-navigationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build a filterable product listing page (PLP) where shoppers can narrow results by multiple attributes simultaneously — size, color, brand, price range, rating — while keeping the URL in sync so filters are shareable, bookmarkable, and crawlable by search engines. Good faceted navigation drives measurable conversion lift on catalogs with more than 50 SKUs.
/shoes/running?color=black&size=10)| Platform | Recommended Approach | Why | |----------|---------------------|-----| | Shopify | Enable native collection filters (Online Store 2.0 themes) + install Search & Discovery app (free) | Dawn, Sense, and other OS2.0 themes support native storefront filtering via the Storefront API; Search & Discovery adds synonym, boosting, and filter configuration from the admin | | WooCommerce | Install FiboSearch (paid, $49/yr) or WooCommerce Product Filters (free) plugin | FiboSearch adds AJAX-powered facets with price slider, color swatches, and stock filter; the free Product Filters plugin covers basic attribute filtering with URL state | | BigCommerce | Enable Faceted Search in Storefront → Search settings (built-in on Cornerstone and most themes) | BigCommerce Faceted Search is native to the platform — configure which product attributes appear as facets in the admin; no app required | | Custom / Headless | Build with Algolia InstantSearch or Elasticsearch + URL state management | Full control over facet logic, disjunctive filtering, and count freshness; see implementation details below |
Using Search & Discovery app (recommended):
Theme-level filter configuration (Dawn theme):
For Shopify Plus: Use Shopify Flow to tag products with filterable attributes automatically when new products are added.
Option A: FiboSearch (recommended for advanced filtering):
Option B: WooCommerce Product Filters (free):
[woof] in your shop page sidebar or above the product gridURL state: Both plugins write active filters to the URL as query parameters, making results shareable and bookmarkable.
Note: Faceted Search requires Stencil-based themes (Cornerstone and most modern BigCommerce themes). Legacy Blueprint themes do not support it.
For headless storefronts, implement URL-state-driven filtering with your search backend:
URL state schema — all active filters live in query params:
/products/shoes?brand=Nike&brand=Adidas&color=black&size=10&price_min=50&price_max=150&sort=price_asc&page=1
Parse and build URL state:
// 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 query with disjunctive facets (OR within a facet, AND between facets):
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,
});
Toggle filter and push URL state:
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;
}
On mobile, the filter panel should appear as a bottom drawer triggered by a "Filter" button — not an always-visible sidebar that takes up half the screen.
position: fixed; bottom: 0 drawer on screens below 640px; trigger with a "Filter (N)" button where N is the active filter countAll platforms should show applied filters as dismissible pills above the product grid:
[woof_active_filters] shortcode to show them separatelytoggleFilter to remove it| Problem | Solution |
|---------|----------|
| Back button reloads page instead of removing last filter | Use history.pushState (not replaceState) for each filter change |
| Facet counts go stale after first filter selection | Re-fetch facet counts on every filter change using Algolia disjunctive faceting or Search & Discovery's built-in count refresh |
| Mobile filter panel overlaps content | Use a drawer/modal on mobile triggered by a "Filters" button; never show a sidebar on screens below 640px |
| SEO duplicate content from facet URLs | Add rel="noindex" or canonical tags for non-primary facet combinations; this is configured in Shopify's Search & Discovery SEO settings |
| Price range thumbs overlap | Clamp max thumb minimum to current min+step and min thumb maximum to current max-step on every change |
tools
Let shoppers save products to a wishlist, share it with friends, and get notified when saved items come back in stock or drop in price
development
Build a themeable storefront with design tokens and CSS custom properties that supports white-labeling, multi-brand variants, and dark mode
development
Speed up product discovery with instant search suggestions, fuzzy typo matching, and category-aware results powered by Algolia or Elasticsearch
development
Build a mobile-first storefront with thumb-friendly navigation, sticky add-to-cart buttons, and touch-optimized components for high mobile conversion