The numericMenu widget displays a list of predefined numeric ranges that users can select to filter results. It’s ideal for price ranges, size ranges, or any scenario where you want to offer preset filtering options.
Usage
const numericMenu = instantsearch . widgets . numericMenu ({
container: '#price-menu' ,
attribute: 'price' ,
items: [
{ label: 'All' },
{ label: 'Less than $10' , end: 10 },
{ label: '$10 - $100' , start: 10 , end: 100 },
{ label: '$100 - $500' , start: 100 , end: 500 },
{ label: 'More than $500' , start: 500 },
],
});
search . addWidget ( numericMenu );
Examples
Price Ranges
instantsearch . widgets . numericMenu ({
container: '#price-ranges' ,
attribute: 'price' ,
items: [
{ label: 'All prices' },
{ label: 'Under $50' , end: 50 },
{ label: '$50 to $200' , start: 50 , end: 200 },
{ label: '$200 to $500' , start: 200 , end: 500 },
{ label: 'Over $500' , start: 500 },
],
});
File Size Ranges
instantsearch . widgets . numericMenu ({
container: '#file-size' ,
attribute: 'file_size' ,
items: [
{ label: 'All sizes' },
{ label: 'Small (< 1MB)' , end: 1048576 },
{ label: 'Medium (1-10MB)' , start: 1048576 , end: 10485760 },
{ label: 'Large (> 10MB)' , start: 10485760 },
],
});
instantsearch . widgets . numericMenu ({
container: '#price' ,
attribute: 'price' ,
items: [
{ label: 'All' },
{ label: 'Budget' , end: 50 },
{ label: 'Mid-range' , start: 50 , end: 200 },
{ label: 'Premium' , start: 200 },
],
transformItems : ( items ) =>
items . map (( item ) => ({
... item ,
label: ` ${ item . label } ( ${ item . count } )` ,
})),
});
Options
container
string | HTMLElement
required
CSS Selector or HTMLElement to insert the widget.
The name of the numeric attribute to filter on. Must be declared as an attribute for faceting.
Array of objects defining the numeric ranges. Each item can have:
label (string, required): Display label for the range
start (number, optional): Lower bound (inclusive, >=)
end (number, optional): Upper bound (inclusive, <=)
Omitting both start and end creates an “All” option.
Function to transform the items before rendering. ( items : object []) => object []
Templates to customize the widget rendering. Template for each item. Receives:
attribute: The attribute name
label: The label for the option
value: Encoded bounds object
isRefined: Whether selected
url: URL for this refinement
CSS classes to add to the widget elements. CSS class for the root element.
CSS class when no refinements are available.
CSS class for the list element.
CSS class for the selected item.
CSS class for the label text.
CSS class for the radio button.
HTML Output
< div class = "ais-NumericMenu" >
< ul class = "ais-NumericMenu-list" >
< li class = "ais-NumericMenu-item" >
< label class = "ais-NumericMenu-label" >
< input class = "ais-NumericMenu-radio" type = "radio" name = "NumericMenu" />
< span class = "ais-NumericMenu-labelText" > All prices </ span >
</ label >
</ li >
< li class = "ais-NumericMenu-item ais-NumericMenu-item--selected" >
< label class = "ais-NumericMenu-label" >
< input class = "ais-NumericMenu-radio" type = "radio" name = "NumericMenu" checked />
< span class = "ais-NumericMenu-labelText" > $10 - $100 </ span >
</ label >
</ li >
</ ul >
</ div >
Item Definition
The items array defines the numeric ranges:
[
// "All" option - no filtering
{ label: 'All' },
// Upper bound only: value <= 10
{ label: 'Less than $10' , end: 10 },
// Both bounds: 10 <= value <= 100
{ label: '$10 to $100' , start: 10 , end: 100 },
// Lower bound only: value >= 500
{ label: 'More than $500' , start: 500 },
]
Requirements
The attribute must be declared as an attribute for faceting in your Algolia index settings. The values must be JavaScript numbers (not strings).