Provides AI-powered filter suggestions based on the current search context and user behavior.
Usage
import instantsearch from 'instantsearch.js';
import { filterSuggestions } from 'instantsearch.js/es/widgets';
const search = instantsearch({
indexName: 'instant_search',
searchClient
});
search.addWidgets([
filterSuggestions({
container: '#filter-suggestions',
agentId: 'YOUR_AGENT_ID',
attributes: ['brand', 'category', 'color']
})
]);
search.start();
Parameters
container
string | HTMLElement
required
CSS selector or HTMLElement to insert the widget.
The agent ID for the AI filter suggestions.
Array of attribute names to get filter suggestions for.
Maximum number of filter suggestions to display.
Debounce time in milliseconds before requesting suggestions.
Number of hits to sample for generating suggestions.
Function to transform the suggestions before rendering.(items: FilterSuggestion[]) => FilterSuggestion[]
Custom transport configuration for the suggestions API.
Templates to use for the widget.
Template for the widget header. Set to false to hide the header.Receives { suggestions, isLoading }.
Template for each filter suggestion item.Receives { suggestion, refine }.
Template to display when there are no suggestions.
CSS classes to add to the widget elements.
CSS class for the root element.
CSS class for the header.
CSS class for the list element.
CSS class for each suggestion item.
CSS class for the empty state.
Examples
Basic usage
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category', 'color'],
maxSuggestions: 5
});
Custom item template
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category'],
templates: {
item({ suggestion, refine }) {
return `
<button
class="filter-chip"
onclick="${() => refine(suggestion)}"
>
${suggestion.label}
<span class="count">${suggestion.count}</span>
</button>
`;
}
}
});
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category', 'color'],
templates: {
header({ suggestions, isLoading }) {
if (isLoading) {
return '<h3>Loading suggestions...</h3>';
}
return `<h3>Suggested Filters (${suggestions.length})</h3>`;
},
item({ suggestion, refine }) {
return `
<div class="suggestion" onclick="${() => refine(suggestion)}">
<strong>${suggestion.attribute}</strong>: ${suggestion.value}
</div>
`;
}
}
});
Empty state
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category'],
templates: {
item({ suggestion, refine }) {
return `<button onclick="${() => refine(suggestion)}">${suggestion.label}</button>`;
},
empty() {
return '<p class="no-suggestions">No filter suggestions available.</p>';
}
}
});
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category'],
templates: {
header: false,
item({ suggestion, refine }) {
return `<button onclick="${() => refine(suggestion)}">${suggestion.label}</button>`;
}
}
});
With debounce
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category', 'color'],
debounceMs: 300,
maxSuggestions: 8
});
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category', 'price'],
transformItems(suggestions) {
// Filter out low-count suggestions
return suggestions.filter(s => s.count > 5);
},
templates: {
item({ suggestion, refine }) {
return `
<button onclick="${() => refine(suggestion)}">
${suggestion.label} (${suggestion.count})
</button>
`;
}
}
});
Styled as chips
filterSuggestions({
container: '#filter-suggestions',
agentId: 'filter-agent-123',
attributes: ['brand', 'category', 'color', 'size'],
templates: {
header: 'Refine by',
item({ suggestion, refine }, { html }) {
return html`
<button
class="chip"
onclick=${() => refine(suggestion)}
>
<span class="chip-label">${suggestion.value}</span>
<span class="chip-count">${suggestion.count}</span>
</button>
`;
}
}
});
HTML output
<div class="ais-FilterSuggestions">
<div class="ais-FilterSuggestions-header">
Suggested Filters
</div>
<ul class="ais-FilterSuggestions-list">
<li class="ais-FilterSuggestions-item">
<!-- Item template content -->
</li>
<!-- More suggestions -->
</ul>
</div>
Loading state
<div class="ais-FilterSuggestions">
<div class="ais-FilterSuggestions-header">
Loading suggestions...
</div>
<ul class="ais-FilterSuggestions-list">
<li class="ais-FilterSuggestions-item ais-FilterSuggestions-item--skeleton">
<!-- Skeleton loader -->
</li>
</ul>
</div>
Notes
- Requires Algolia AI to be enabled on your account.
- Suggestions are generated based on search context and user behavior.
- The widget automatically handles loading and empty states.
- Clicking a suggestion applies the corresponding filter.
- Perfect for helping users discover relevant filters.
- Works best with query-based search interfaces.