The sortBy widget provides a dropdown selector to let users change the sorting of search results. It can switch between different indices or sorting strategies.
Usage
const sortBy = instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , value: 'products' },
{ label: 'Price (asc)' , value: 'products_price_asc' },
{ label: 'Price (desc)' , value: 'products_price_desc' },
],
});
search . addWidget ( sortBy );
Examples
Basic Sort By
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Featured' , value: 'products' },
{ label: 'Price: Low to High' , value: 'products_price_asc' },
{ label: 'Price: High to Low' , value: 'products_price_desc' },
{ label: 'Newest First' , value: 'products_date_desc' },
],
});
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , value: 'products' },
{ label: 'Price Ascending' , value: 'products_price_asc' },
{ label: 'Price Descending' , value: 'products_price_desc' },
],
transformItems : ( items ) =>
items . map (( item ) => ({
... item ,
label: `Sort by: ${ item . label } ` ,
})),
});
Using Sorting Strategies (Composition Mode)
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , strategy: 'relevance' },
{ label: 'Price: Low to High' , strategy: 'price_asc' },
{ label: 'Price: High to Low' , strategy: 'price_desc' },
],
});
Options
container
string | HTMLElement
required
CSS Selector or HTMLElement to insert the widget.
Array of objects defining the different sorting options. Each item can be: Index-based (traditional mode):
label (string, required): Display label
value (string, required): Name of the index to use
Strategy-based (composition mode):
label (string, required): Display label
strategy (string, required): Name of the sorting strategy
Function to transform the items before rendering. ( items : object []) => object []
CSS classes to add to the widget elements. CSS class for the root element.
CSS class for the select element.
CSS class for each option element.
HTML Output
< div class = "ais-SortBy" >
< select class = "ais-SortBy-select" aria-label = "Sort results by" >
< option class = "ais-SortBy-option" value = "products" selected >
Relevance
</ option >
< option class = "ais-SortBy-option" value = "products_price_asc" >
Price (asc)
</ option >
< option class = "ais-SortBy-option" value = "products_price_desc" >
Price (desc)
</ option >
</ select >
</ div >
Index-Based Sorting
Traditional approach using replica indices:
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , value: 'products' },
{ label: 'Price (Low)' , value: 'products_price_asc' },
{ label: 'Price (High)' , value: 'products_price_desc' },
],
});
Requires creating replica indices in Algolia dashboard with different ranking formulas.
Strategy-Based Sorting
Modern approach using composition mode (Algolia Composable UI):
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , strategy: 'default' },
{ label: 'Price: Low to High' , strategy: 'price_asc' },
{ label: 'Price: High to Low' , strategy: 'price_desc' },
{ label: 'Rating' , strategy: 'rating_desc' },
],
});
Strategy-based sorting is only available when using composition mode. Check your Algolia plan for availability.
Setting Up Replica Indices
To use index-based sorting, create replica indices:
Go to your Algolia dashboard
Select your index
Go to “Replicas” tab
Create replicas with custom ranking:
products_price_asc: Sort by price ascending
products_price_desc: Sort by price descending
products_date_desc: Sort by date descending
Default Selection
The first item in the array is selected by default, or you can specify the initial index:
const search = instantsearch ({
indexName: 'products_price_asc' , // Start with price sorting
searchClient ,
});
instantsearch . widgets . sortBy ({
container: '#sort-by' ,
items: [
{ label: 'Relevance' , value: 'products' },
{ label: 'Price (asc)' , value: 'products_price_asc' },
],
});
Custom Styling
.ais-SortBy-select {
padding : 8 px 32 px 8 px 12 px ;
border : 1 px solid #ddd ;
border-radius : 4 px ;
font-size : 14 px ;
background-image : url ( 'data:image/svg+xml;...' );
background-repeat : no-repeat ;
background-position : right 8 px center ;
}
.ais-SortBy-select:focus {
outline : none ;
border-color : #3a96cf ;
}