Introduction
instantsearch.js is a JavaScript library that lets you create an instant search results experience using Algolia’s REST API.
A search results page is made up of individual components, also known as widgets. Widgets are UI components for either the search input (search bar, facets/filters, etc.) or the search output (actual results).
Each widget is independent, and their rendering is bound to the search. They follow the instantsearch.js lifecycle:
- Configuration: each widget adds new query parameters to the underlying Algolia API client.
- Initial rendering: before the initial search, the widget may update the UI.
- Rendering: on each search, after the results come back from Algolia, the widgets update themselves.
The library is open-source, based on React.js and hosted on GitHub: algolia/instantsearch.js. All contributions are welcome.
Setup
From a CDN
Use a built version of instantsearch.js from the jsDelivr CDN:
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.min.css">
<script src="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.min.js"></script>
You will then have access to the instantsearch function in the global scope (window).
The jsDelivr CDN is highly available with over 110 locations in the world.
From NPM
If you have a JavaScript build system, you can install instantsearch.js from NPM:
npm install instantsearch.js --save
var instantsearch = require('instantsearch.js');
You need to manually load the companion CSS file into your page.
Bower
Use jsDelivr builds to install with bower:
bower install https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.js
Light build
We created a light build that uses Preact instead of React internally.
We recommend using the light build for new users and switching to it for existing users if you are not using React on your side.
To use it, require this file:
<script src="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch-preact.min.js"></script>
React InstantSearch
We also have a dedicated React library if you are already using React: React InstantSearch.
Initialization
To initialize the instantsearch.js library, you need an Algolia account with a configured and non-empty index.
var search = instantsearch({
appId: '$appId',
apiKey: '$apiKey',
indexName: '$indexName',
urlSync: true
});
instantsearch(options);
Parameters
options.appId…
(string)
The Algolia application ID
options.apiKey…
(string)
The Algolia search-only API key
options.indexName…
(string)
The name of the main index
options.numberLocale…
(string)
The locale used to display numbers. This will be passed to Number.prototype.toLocaleString()
options.searchFunction…
(function)
A hook that will be called each time a search needs to be done, with the helper as a parameter. It’s your responsibility to call helper.search(). This option allows you to avoid doing searches at page load for example.
options.createAlgoliaClient…
(function)
Allows you to provide your own algolia client instead of the one instantiated internally by instantsearch.js. Useful in situations where you need to setup complex options on the client or if you need to share it easily. Usage: createAlgoliaClient: function(algoliasearch, appId, apiKey) { return anyCustomClient; } We forward algoliasearch which is the original algoliasearch module imported inside instantsearch.js
options.searchParameters…
(Object)
Additional parameters to pass to the Algolia API. Full documentation
options.urlSync…
(Object | boolean)
Url synchronization configuration. Setting to true will synchronize the needed search parameters with the browser url.
options.urlSync.mapping…
(Object)
Object used to define replacement query parameter to use in place of another. Keys are current query parameters and value the new value, e.g. { q: 'query' }.
options.urlSync.threshold…
(number)
Idle time in ms after which a new state is created in the browser history. The default value is 700. The url is always updated at each keystroke but we only create a “previous search state” (activated when click on back button) every 700ms of idle time.
options.urlSync.trackedParameters…
(Array.<string>)
Parameters that will be synchronized in the URL. Default value is ['query', 'attribute:*', 'index', 'page', 'hitsPerPage']. attribute:* means all the faceting attributes will be tracked. You can track only some of them by using […, ‘attribute:color’, ‘attribute:categories’]. All other possible values are all the attributes of the Helper SearchParameters. There’s a special is_v parameter that will get added everytime, it tracks the version of instantsearch.js linked to the url.
options.urlSync.useHash…
(boolean)
If set to true, the url will be hash based. Otherwise, it’ll use the query parameters using the modern history API.
options.urlSync.getHistoryState…
(function)
Pass this function to override the default history API state we set to null. For example this could be used to force passing {turbolinks: true} to the history API every time we update it.
* Required
Use your search-only API key. Your index should also contain data.
You can find your Algolia credentials on the credentials page of your dashboard.
Use the APPLICATION_ID appId, the search only API_KEY apiKey and an index name indexName to configure the required parameters of the instantsearch function.
If you don’t have any indices yet, learn how to push your data with the Algolia getting started guide.
Url synchronization
You can synchronise the current search with the browser url. It provides two benefits:
- Working back/next browser buttons
- Copy and share the current search url
To configure this feature, pass urlSync: true option to instantsearch().
The urlSync option has more parameters, see the instantsearch function documentation.
Adding Widgets
To build your search results page, you need to combine several widgets. Start by adding a searchBox widget, a hits widget, and a pagination widget to build a basic results page.
<div id="search-box"></div>
<script>
// var search = instantsearch..
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for products...'
})
);
</script>
search.addWidget(widget)
Parameters
widget…
(Object)
The widget to add
widget.render…
(function)
Called after each search response has been received
widget.getConfiguration…
(function)
Let the widget update the configuration of the search with new parameters
widget.init…
(function)
Called once before the first search
* Required
Note: instantsearch.js comes with built-in widgets, but you can also build your own custom widgets.
Start
Once all the widgets have been added to the instantsearch instance, start the rendering by calling the start() method.
search.start();
This example shows you how to create a very simple search results page that includes a searchBox, a list of hits and a pagination widget.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.min.css" />
<title>instantsearch.js basics</title>
</head>
<body>
<input type="text" id="search-box" />
<div id="hits-container"></div>
<div id="pagination-container"></div>
<script src="https://cdn.jsdelivr.net/instantsearch.js/1/instantsearch.min.js"></script>
<script>
var search = instantsearch({
appId: 'YourApplicationID',
apiKey: 'YourSearchOnlyAPIKey',
indexName: 'YourIndexName'
});
search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for products...'
})
);
search.addWidget(
instantsearch.widgets.hits({
container: '#hits-container',
templates: {
item: 'Hit {{objectID}}: FIXME'
}
})
);
search.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container'
})
);
search.start();
</script>
</body>
</html>

Events
var search = instantsearch({
appId: '$appId',
apiKey: '$apiKey',
indexName: '$indexName',
urlSync: true
});
var onRenderHandler = function() {};
search.on('render', onRenderHandler);
// on renderHandler will be called
// until removeListener is called
search.removeListener(onRenderHandler);
search.once('render', function(){ });
// triggered once then removed automatically
instantsearch emits events during its lifecycle. The currently supported events are:
render: fired when a rendering of all the widgets has been completed
instantsearch events are based on the Node EventEmitter class. See the example for a quick overview of the API or go to the Node documentation for more details.
Widgets
Basics
searchBox
The search box widget is where you users type their search queries.
search.addWidget(
instantsearch.widgets.searchBox({
container: '#q',
placeholder: 'Search for products',
autofocus: false,
poweredBy: true
})
);
instantsearch.widgets.searchBox(options)
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.placeholder…
(string)
Input’s placeholder
options.poweredBy…
Default:false(boolean | Object)
Define if a “powered by Algolia” link should be added near the input
options.poweredBy.template…
(function | string)
Template used for displaying the link. Can accept a function or a Hogan string.
options.poweredBy.cssClasses…
(number)
CSS classes to add
options.poweredBy.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.poweredBy.cssClasses.link…
(string | Array.<string>)
CSS class to add to the link element
options.wrapInput…
Default:true(boolean)
Wrap the input in a div.ais-search-box
autofocus…
Default:'auto'(boolean | string)
autofocus on the input
options.searchOnEnterKeyPressOnly…
Default:false(boolean)
If set, trigger the search once <Enter> is pressed only
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the wrapping div (if wrapInput set to true)
options.cssClasses.input…
(string | Array.<string>)
CSS class to add to the input
options.queryHook…
(function)
A function that will be called every time a new search would be done. You will get the query as first parameter and a search(query) function to call as the second parameter. This queryHook can be used to debounce the number of searches done from the searchBox.
* Required
For better results, we suggest that you configure at least the attributeToIndex and customRanking of your index.
hits
The hits widget is the main component that displays results from Algolia. It accepts a Mustache template string or a function returning a string. See the templates section.
search.addWidget(
instantsearch.widgets.hits({
container: '#hits-container',
templates: {
empty: 'No results',
item: '<strong>Hit {{objectID}}</strong>: {{{_highlightResult.name.value}}}'
},
hitsPerPage: 6
})
);
instantsearch.widgets.hits(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.hitsPerPage…
Default:20(number)
The number of hits to display per page
options.templates…
(Object)
Templates to use for the widget
options.templates.empty…
Default:''(string | function)
Template to use when there are no results.
options.templates.item…
Default:''(string | function)
Template to use for each result. This template will receive an object containing a single record.
options.templates.allItems…
Default:''(string | function)
Template to use for the list of all results. (Can’t be used with item template). This template will receive a complete SearchResults result object, this object contains the key hits that contains all the records retrieved.
options.transformData…
(Object)
Method to change the object passed to the templates
options.transformData.empty…
(function)
Method used to change the object passed to the empty template
options.transformData.item…
(function)
Method used to change the object passed to the item template
options.transformData.allItems…
(function)
Method used to change the object passed to the allItems template
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the wrapping element
options.cssClasses.empty…
(string | Array.<string>)
CSS class to add to the wrapping element when no results
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each result
* Required
For better control over what kind of data is returned, we suggest you configure the attributeToRetrieve and attributeToHighlight of your index.
Infinite hits
The infinite hits widget is like the hits widget but instead of relying on an external pagination widget, it displays a button to load more results.
It will display the results as one continuous long page. Its usage is particularly recommended in a mobile context. Even though it is not incompatible, it does not go well with the pagination widget.
It accepts a Mustache template string or a function returning a string. See the templates section.
search.addWidget(
instantsearch.widgets.infiniteHits({
container: '#infinite-hits-container',
templates: {
empty: 'No results',
item: '<strong>Hit {{objectID}}</strong>: {{{_highlightResult.name.value}}}'
},
hitsPerPage: 3
})
);
instantsearch.widgets.infiniteHits(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.hitsPerPage…
Default:20(number)
The number of hits to display per page
options.templates…
(Object)
Templates to use for the widget
options.templates.empty…
Default:""(string | function)
Template to use when there are no results.
options.templates.item…
Default:""(string | function)
Template to use for each result. This template will receive an object containing a single record.
options.showMoreLabel…
Default:"Show more results"(string)
label used on the show more button
options.transformData…
(Object)
Method to change the object passed to the templates
options.transformData.empty…
(function)
Method used to change the object passed to the empty template
options.transformData.item…
(function)
Method used to change the object passed to the item template
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the wrapping element
options.cssClasses.empty…
(string | Array.<string>)
CSS class to add to the wrapping element when no results
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each result
* Required
For better control over what kind of data is returned, we suggest you configure the attributeToRetrieve and attributeToHighlight of your index.
hitsPerPageSelector
The hitsPerPageSelector widget lets you select the number of results you want
displayed at once.
search.addWidget(
instantsearch.widgets.hitsPerPageSelector({
container: '#hits-per-page-selector',
options: [
{value: 6, label: '6 per page'},
{value: 12, label: '12 per page'},
{value: 24, label: '24 per page'}
]
})
);
instantsearch.widgets.hitsPerPageSelector(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.options…
(Array)
Array of objects defining the different values and labels
options.options[0].value…
(number)
number of hits to display per page
options.options[0].label…
(string)
Label to display in the option
options.autoHideContainer…
Default:false(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string | Array.<string>)
CSS classes added to the parent <select>
options.cssClasses.item…
(string | Array.<string>)
CSS classes added to each <option>
* Required
The hits widget lets you define the default number of results
displayed. This value must be defined in the options parameter.
Navigation
pagination
The pagination widget provides the ability to navigate through results
pages.
search.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container',
maxPages: 20,
// default is to scroll to 'body', here we disable this behavior
scrollTo: false
})
);
instantsearch.widgets.pagination(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.labels…
(Object)
Text to display in the various links (prev, next, first, last)
options.labels.previous…
(string)
Label for the Previous link
options.labels.next…
(string)
Label for the Next link
options.labels.first…
(string)
Label for the First link
options.labels.last…
(string)
Label for the Last link
options.maxPages…
(number)
The max number of pages to browse
options.padding…
Default:3(number)
The number of pages to display on each side of the current page
options.scrollTo…
Default:'body'(string | DOMElement | boolean)
Where to scroll after a click, set to false to disable
options.showFirstLast…
Default:true(boolean)
Define if the First and Last links should be displayed
options.autoHideContainer…
Default:true(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string | Array.<string>)
CSS classes added to the parent <ul>
options.cssClasses.item…
(string | Array.<string>)
CSS classes added to each <li>
options.cssClasses.link…
(string | Array.<string>)
CSS classes added to each link
options.cssClasses.page…
(string | Array.<string>)
CSS classes added to page <li>
options.cssClasses.previous…
(string | Array.<string>)
CSS classes added to the previous <li>
options.cssClasses.next…
(string | Array.<string>)
CSS classes added to the next <li>
options.cssClasses.first…
(string | Array.<string>)
CSS classes added to the first <li>
options.cssClasses.last…
(string | Array.<string>)
CSS classes added to the last <li>
options.cssClasses.active…
(string | Array.<string>)
CSS classes added to the active <li>
options.cssClasses.disabled…
(string | Array.<string>)
CSS classes added to the disabled <li>
* Required
menu
The menu widget provides a way to navigate through results based on a single attribute.
Only one value can be selected at a time. This can be used for navigating through the categories
of an e-commerce website.
search.addWidget(
instantsearch.widgets.menu({
container: '#categories',
attributeName: 'categories',
limit: 10,
templates: {
header: 'Categories'
}
})
);
instantsearch.widgets.menu(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for faceting
options.sortBy…
Default:['count:desc', 'name:asc'](Array.<string> | function)
How to sort refinements. Possible values: count|isRefined|name:asc|name:desc. You can also use a sort function that behaves like the standard Javascript compareFunction.
options.limit…
Default:10(string)
How many facets values to retrieve
options.showMore…
Default:false(object | boolean)
Limit the number of results and display a showMore button
options.showMore.templates…
(object)
Templates to use for showMore
options.showMore.templates.active…
(object)
Template used when showMore was clicked
options.showMore.templates.inactive…
(object)
Template used when showMore not clicked
options.showMore.limit…
(object)
Max number of facets values to display when showMore is clicked
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.item…
(string | function)
Item template, provided with name, count, isRefined, url data properties
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Method to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when there are no items in the menu
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.cssClasses.link…
(string | Array.<string>)
CSS class to add to each link (when using the default template)
options.cssClasses.count…
(string | Array.<string>)
CSS class to add to each count element (when using the default template)
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
hierarchicalMenu
The hierarchical menu is a widget that lets the user explore a tree-like structure.
This is commonly used for multi-level categorization of products on e-commerce websites.
From a UX point of view, we suggest not displaying more than two levels deep.
search.addWidget(
instantsearch.widgets.hierarchicalMenu({
container: '#hierarchical-categories',
attributes: ['hierarchicalCategories.lvl0', 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2'],
templates: {
header: 'Hierarchical categories'
}
})
);
instantsearch.widgets.hierarchicalMenu(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributes…
(Array.<string>)
Array of attributes to use to generate the hierarchy of the menu. See the example for the convention to follow.
options.limit…
Default:10(number)
How much facet values to get
options.separator…
Default:">"(string)
Separator used in the attributes to separate level values.
options.rootPath…
(string)
Prefix path to use if the first level is not the root level.
options.showParentLevel…
Default:false(string)
Show the parent level of the current refined value
options.sortBy…
Default:['name:asc'](Array.<string> | function)
How to sort refinements. Possible values: count|isRefined|name:asc|name:desc. You can also use a sort function that behaves like the standard Javascript compareFunction.
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
Default:''(string | function)
Header template (root level only)
options.templates.item…
(string | function)
Item template, provided with name, count, isRefined, url data properties
options.templates.footer…
Default:''(string | function)
Footer template (root level only)
options.transformData.item…
(function)
Method to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when there are no items in the menu
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.depth…
(string | Array.<string>)
CSS class to add to each item element to denote its depth. The actual level will be appended to the given class name (ie. if depth is given, the widget will add depth0, depth1, … according to the level of each item).
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.cssClasses.link…
(string | Array.<string>)
CSS class to add to each link (when using the default template)
options.cssClasses.count…
(string | Array.<string>)
CSS class to add to each count element (when using the default template)
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute used for faceting must be an object that follows a specific convention.
For example, to build the example menu, our objects are defined like this:
{
"objectID": 4815162342,
"hierarchicalCategories": {
"lvl0": "Appliances"
"lvl1": "Appliances > Air Conditioners"
"lvl2": "Appliances > Air Conditioners > Portable Air Conditioners"
}
}
All attributes (hierarchicalCategories.lvl0/1/2) should be defined as
attributesForFaceting in your index configuration.
Each level must repeat the parent breadcrumb.
Filters
refinementList
This filtering widget lets the user refine the search results. You can specify if you want filters to be ORed or ANDed. For example, if you filter on
a and b with OR,
results with either the value a or b will match.
search.addWidget(
instantsearch.widgets.refinementList({
container: '#brands',
attributeName: 'brand',
operator: 'or',
limit: 10,
templates: {
header: 'Brands'
}
})
);
instantsearch.widgets.refinementList(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for faceting
options.operator…
Default:'or'(string)
How to apply refinements. Possible values: or, and
options.sortBy…
Default:['count:desc', 'name:asc'](Array.<string> | function)
How to sort refinements. Possible values: count:asc|count:desc|name:asc|name:desc|isRefined. You can also use a sort function that behaves like the standard Javascript compareFunction.
options.limit…
Default:10(string)
How much facet values to get. When the show more feature is activated this is the minimum number of facets requested (the show more button is not in active state).
options.searchForFacetValues…
Default:false(object | boolean)
Add a search input to let the user search for more facet values
options.searchForFacetValues.placeholder…
(string)
Value of the search field placeholder
options.searchForFacetValues.templates…
(string)
Templates to use for search for facet values
options.searchForFacetValues.templates.noResults…
(string)
Templates to use for search for facet values
options.showMore…
Default:false(object | boolean)
Limit the number of results and display a showMore button
options.showMore.templates…
(object)
Templates to use for showMore
options.showMore.templates.active…
(object)
Template used when showMore was clicked
options.showMore.templates.inactive…
(object)
Template used when showMore not clicked
options.showMore.limit…
(object)
Max number of facets values to display when showMore is clicked
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template, provided with refinedFacetsCount data property
options.templates.item…
(string | function)
Item template, provided with name, count, isRefined, url data properties
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Function to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no items in the refinement list
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.cssClasses.label…
(string | Array.<string>)
CSS class to add to each label element (when using the default template)
options.cssClasses.checkbox…
(string | Array.<string>)
CSS class to add to each checkbox element (when using the default template)
options.cssClasses.count…
(string | Array.<string>)
CSS class to add to each count element (when using the default template)
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
numericRefinementList
This widget lets the user refine search results based on a numerical attribute. You can specify a specific number or a range.
search.addWidget(
instantsearch.widgets.numericRefinementList({
container: '#popularity',
attributeName: 'popularity',
options: [
{name: 'All'},
{end: 500, name: 'less than 500'},
{start: 500, end: 2000, name: 'between 500 and 2000'},
{start: 2000, name: 'more than 2000'}
],
templates: {
header: 'Popularity'
}
})
);
instantsearch.widgets.numericRefinementList(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for filtering
options.options…
(Array.<Object>)
List of all the options
options.options[].name…
(string)
Name of the option
options.options[].start…
(number)
Low bound of the option (>=)
options.options[].end…
(number)
High bound of the option (<=)
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.item…
(string | function)
Item template, provided with name, isRefined, url data properties
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Function to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.label…
(string | Array.<string>)
CSS class to add to each link element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.radio…
(string | Array.<string>)
CSS class to add to each radio element (when using the default template)
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
toggle
This widget provides an on/off filtering feature based on an attribute value.
Note that if you provide an “off” option, it will be refined at initialization.
search.addWidget(
instantsearch.widgets.toggle({
container: '#free-shipping',
attributeName: 'free_shipping',
label: 'Free Shipping',
values: {
on: true,
off: false
},
templates: {
header: 'Shipping'
}
})
);
instantsearch.widgets.toggle(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for faceting (eg. “free_shipping”)
options.label…
(string)
Human-readable name of the filter (eg. “Free Shipping”)
options.values…
(Object)
Lets you define the values to filter on when toggling
options.values.on…
Default:true(string | number | boolean)
Value to filter on when checked
options.values.off…
(string | number | boolean)
Value to filter on when unchecked element (when using the default template). By default when switching to off, no refinement will be asked. So you will get both true and false results. If you set the off value to false then you will get only objects having false has a value for the selected attribute.
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.item…
(string | function)
Item template, provided with name, count, isRefined, url data properties count is always the number of hits that would be shown if you toggle the widget. We also provide onFacetValue and offFacetValue objects with according counts.
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Function to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when there are no results
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.cssClasses.label…
(string | Array.<string>)
CSS class to add to each label element (when using the default template)
options.cssClasses.checkbox…
(string | Array.<string>)
CSS class to add to each checkbox element (when using the default template)
options.cssClasses.count…
(string | Array.<string>)
CSS class to add to each count
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
rangeSlider
The rangeSlider widget lets users filter results within a numerical range, based on an attribute.
The min and max values are automatically computed by Algolia using the data in the index.
search.addWidget(
instantsearch.widgets.rangeSlider({
container: '#price',
attributeName: 'price',
templates: {
header: 'Price'
},
tooltips: {
format: function(rawValue) {
return '$' + Math.round(rawValue).toLocaleString();
}
}
})
);
instantsearch.widgets.rangeSlider(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for faceting
options.tooltips…
Default:true(boolean | Object)
Should we show tooltips or not. The default tooltip will show the raw value. You can also provide tooltips: {format: function(rawValue) {return '$' + Math.round(rawValue).toLocaleString()}} So that you can format the tooltip display value as you want
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
Default:''(string | function)
Header template
options.templates.footer…
Default:''(string | function)
Footer template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no refinements available
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.pips…
Default:true(boolean | object)
Show slider pips.
options.step…
Default:1(boolean | object)
Every handle move will jump that number of steps.
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
options.min…
(number)
Minimal slider value, default to automatically computed from the result set
options.max…
(number)
Maximal slider value, defaults to automatically computed from the result set
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
The values inside this attribute must be JavaScript numbers and not strings.
priceRanges
This filtering widget lets the user choose a price range. The ranges are dynamically computed based on the returned results.
search.addWidget(
instantsearch.widgets.priceRanges({
container: '#price-ranges',
attributeName: 'price',
labels: {
currency: '$',
separator: 'to',
button: 'Go'
},
templates: {
header: 'Price'
}
})
);
instantsearch.widgets.priceRanges(options);
Parameters
options.container…
(string | DOMElement)
Valid CSS Selector as a string or DOMElement
options.attributeName…
(string)
Name of the attribute for faceting
options.templates…
(Object)
Templates to use for the widget
options.templates.item…
(string | function)
Item template. Template data: from, to and currency
options.currency…
Default:'$'(string)
The currency to display
options.labels…
(Object)
Labels to use for the widget
options.labels.separator…
(string | function)
Separator label, between min and max
options.labels.button…
(string | function)
Button label
options.autoHideContainer…
Default:true(boolean)
Hide the container when no refinements available
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the wrapping list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to the active item element
options.cssClasses.link…
(string | Array.<string>)
CSS class to add to each link element
options.cssClasses.form…
(string | Array.<string>)
CSS class to add to the form element
options.cssClasses.label…
(string | Array.<string>)
CSS class to add to each wrapping label of the form
options.cssClasses.input…
(string | Array.<string>)
CSS class to add to each input of the form
options.cssClasses.currency…
(string | Array.<string>)
CSS class to add to each currency element of the form
options.cssClasses.separator…
(string | Array.<string>)
CSS class to add to the separator of the form
options.cssClasses.button…
(string | Array.<string>)
CSS class to add to the submit button of the form
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
The values inside this attribute must be JavaScript numbers and not strings.
numericSelector
This filtering widget lets the user choose between numerical refinements from a dropdown menu.
search.addWidget(
instantsearch.widgets.numericSelector({
container: '#popularity-selector',
attributeName: 'popularity',
operator: '>=',
options: [
{label: 'Top 10', value: 9900},
{label: 'Top 100', value: 9800},
{label: 'Top 500', value: 9700}
]
})
);
instantsearch.widgets.numericSelector(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the numeric attribute to use
options.options…
(Array)
Array of objects defining the different values and labels
options.options[i].value…
(number)
The numerical value to refine with
options.options[i].label…
(string)
Label to display in the option
options.operator…
Default:'='(string)
The operator to use to refine
options.autoHideContainer…
Default:false(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string | Array.<string>)
CSS classes added to the parent <select>
options.cssClasses.item…
(string | Array.<string>)
CSS classes added to each <option>
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
The values inside this attribute must be JavaScript numbers and not strings.
starRating
This widget lets the user refine search results by clicking on stars. The stars are based on the selected
attributeName. The underlying rating attribute needs to have from 0 to max stars.
search.addWidget(
instantsearch.widgets.starRating({
container: '#stars',
attributeName: 'rating',
max: 5,
labels: {
andUp: '& Up'
}
})
);
instantsearch.widgets.starRating(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.attributeName…
(string)
Name of the attribute for filtering
options.max…
(number)
The maximum rating value
options.labels…
(Object)
Labels used by the default template
options.labels.andUp…
(string)
The label suffixed after each line
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.item…
(string | function)
Item template, provided with name, count, isRefined, url data properties
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Function to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to add to the wrapping elements
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.list…
(string | Array.<string>)
CSS class to add to the list element
options.cssClasses.item…
(string | Array.<string>)
CSS class to add to each item element
options.cssClasses.link…
(string | Array.<string>)
CSS class to add to each link element
options.cssClasses.disabledLink…
(string | Array.<string>)
CSS class to add to each disabled link (when using the default template)
options.cssClasses.star…
(string | Array.<string>)
CSS class to add to each star element (when using the default template)
options.cssClasses.emptyStar…
(string | Array.<string>)
CSS class to add to each empty star element (when using the default template)
options.cssClasses.active…
(string | Array.<string>)
CSS class to add to each active element
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
The attribute defined in attributeName must be defined as an
attributesForFaceting in your index configuration.
The values inside this attribute must be JavaScript numbers and not strings.
clearAll
This widget clears all the refinements that are currently applied.
search.addWidget(
instantsearch.widgets.clearAll({
container: '#clear-all',
templates: {
link: 'Reset everything'
},
autoHideContainer: false
})
);
instantsearch.widgets.clearAll(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.excludeAttributes…
(Array.<string>)
List of attributes names to exclude from clear actions
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.link…
(string | function)
Link template
options.templates.footer…
(string | function)
Footer template
options.autoHideContainer…
Default:true(boolean)
Hide the container when there’s no refinement to clear
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.link…
(string | Array.<string>)
CSS class to add to the link element
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
currentRefinedValues
This widget list all the refinements currently applied. It also lets
the user clear them one by one. This widget can also contain a
clear all link to remove all filters.
search.addWidget(
instantsearch.widgets.currentRefinedValues({
container: '#current-refined-values',
clearAll: 'after'
})
);
instantsearch.widgets.currentRefinedValues(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
option.attributes…
(Array)
Attributes configuration
option.attributes[].name…
(string)
Required attribute name
option.attributes[].label…
(string)
Attribute label (passed to the item template)
option.attributes[].template…
(string | function)
Attribute specific template
option.attributes[].transformData…
(function)
Attribute specific transformData
option.clearAll…
Default:'before'(boolean | string)
Clear all position (one of (‘before’, ‘after’, false))
options.onlyListedAttributes…
Default:false(boolean)
Only use declared attributes
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
(string | function)
Header template
options.templates.item…
(string | function)
Item template
options.templates.clearAll…
(string | function)
Clear all template
options.templates.footer…
(string | function)
Footer template
options.transformData.item…
(function)
Function to change the object passed to the item template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no current refinements
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string)
CSS classes added to the root element
options.cssClasses.header…
(string)
CSS classes added to the header element
options.cssClasses.body…
(string)
CSS classes added to the body element
options.cssClasses.clearAll…
(string)
CSS classes added to the clearAll element
options.cssClasses.list…
(string)
CSS classes added to the list element
options.cssClasses.item…
(string)
CSS classes added to the item element
options.cssClasses.link…
(string)
CSS classes added to the link element
options.cssClasses.count…
(string)
CSS classes added to the count element
options.cssClasses.footer…
(string)
CSS classes added to the footer element
options.collapsible…
Default:false(object | boolean)
Hide the widget body and footer when clicking on header
options.collapsible.collapsed…
(boolean)
Initial collapsed state of a collapsible widget
* Required
Sort
sortBySelector
This widget lets you reorder your results. You need multiple indices for this to work. See requirements.
search.addWidget(
instantsearch.widgets.sortBySelector({
container: '#sort-by-container',
indices: [
{name: 'instant_search', label: 'Most relevant'},
{name: 'instant_search_price_asc', label: 'Lowest price'},
{name: 'instant_search_price_desc', label: 'Highest price'}
]
})
);
instantsearch.widgets.sortBySelector(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.indices…
(Array)
Array of objects defining the different indices to choose from.
options.indices[0].name…
(string)
Name of the index to target
options.indices[0].label…
(string)
Label displayed in the dropdown
options.autoHideContainer…
Default:false(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to be added
options.cssClasses.root…
(string | Array.<string>)
CSS classes added to the parent
options.cssClasses.item…
(string | Array.<string>)
CSS classes added to each
* Required
You must have slave indices for every sort order you need. Then
configure their ranking to use a custom attribute as the first criterion.
Find detailed explanations in our FAQ page.
Metadata
stats
This widget lets you display how many results matched the query and how fast the search was.
search.addWidget(
instantsearch.widgets.stats({
container: '#stats-container'
})
);
instantsearch.widgets.stats(options);
Parameters
options.container…
(string | DOMElement)
CSS Selector or DOMElement to insert the widget
options.templates…
(Object)
Templates to use for the widget
options.templates.header…
Default:''(string | function)
Header template
options.templates.body…
(string | function)
Body template, provided with hasManyResults, hasNoResults, hasOneResult, hitsPerPage, nbHits, nbPages, page, processingTimeMS, query
options.templates.footer…
Default:''(string | function)
Footer template
options.transformData.body…
(function)
Function to change the object passed to the body template
options.autoHideContainer…
Default:true(boolean)
Hide the container when no results match
options.cssClasses…
(Object)
CSS classes to add
options.cssClasses.root…
(string | Array.<string>)
CSS class to add to the root element
options.cssClasses.header…
(string | Array.<string>)
CSS class to add to the header element
options.cssClasses.body…
(string | Array.<string>)
CSS class to add to the body element
options.cssClasses.footer…
(string | Array.<string>)
CSS class to add to the footer element
options.cssClasses.time…
(string | Array.<string>)
CSS class to add to the element wrapping the time processingTimeMs
* Required
Analytics
analytics
This widget lets you send search data to your analytic services like Google Analytics, Segment.io, Kissmetrics and others. See example tab on the right side to see example codes of various analytics services.
search.addWidget(
instantsearch.widgets.analytics({
pushFunction: function(formattedParameters, state, results) {
// Google Analytics
// window.ga('set', 'page', '/search/query/?query=' + state.query + '&' + formattedParameters + '&numberOfHits=' + results.nbHits);
// window.ga('send', 'pageView');
// GTM
// dataLayer.push({'event': 'search', 'Search Query': state.query, 'Facet Parameters': formattedParameters, 'Number of Hits': results.nbHits});
// Segment.io
// analytics.page( '[SEGMENT] instantsearch', { path: '/instantsearch/?query=' + state.query + '&' + formattedParameters });
// Kissmetrics
// var objParams = JSON.parse('{"' + decodeURI(formattedParameters.replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}');
// var arrParams = $.map(objParams, function(value, index) {
// return [value];
// });
//
// _kmq.push(['record', '[KM] Viewed Result page', {
// 'Query': state.query ,
// 'Number of Hits': results.nbHits,
// 'Search Params': arrParams
// }]);
// any other analytics service
}
})
);
instantsearch.widgets.analytics(options);
Parameters
options.pushFunction…
(function)
Push function called when data are supposed to be pushed to analytic service
options.delay…
Default:3000(int)
Number of milliseconds between last search key stroke and calling pushFunction
options.triggerOnUIInteraction…
Default:false(boolean)
Trigger pushFunction after click on page or redirecting the page
options.pushInitialSearch…
Default:true(boolean)
Trigger pushFunction after the initial search
* Required
FAQ
Default filters
var search = instantsearch({
[...],
searchParameters: {
hierarchicalFacetsRefinements: { // menu is implemented as a hierarchicalFacetsRefinements
categories: ['Cell Phones']
},
facetsRefinements: {
isPremium: [true]
},
disjunctiveFacetsRefinements: {
brand: ['Samsung', 'Apple']
},
// Add to "facets" all attributes for which you
// do NOT have a widget defined
facets: ['isPremium']
},
});
// Below is just a common widget configuration, to show
// how it interacts with the above searchParameters
search.addWidget(
instantsearch.widgets.menu({
[...],
attributeName: 'categories'
})
);
search.addWidget(
instantsearch.widgets.refinementList({
attributeName: 'brand',
operator: 'or'
})
);
Sometimes you might want to automatically add some filters on the first page
load. Maybe automatically filter on Cell Phones made by either Samsung or
Apple, or only display items that are somehow “premium”.
If you are already using a widget to perform a filter on that attribute (like
the menu or refinementList widgets), you can just use the
searchParameters.facetsRefinements or searchParameters.disjunctiveFacetsRefinements (for refinementList) and searchParameters.hierarchicalFacetsRefinements (for menu) attribute option when instantiating instantsearch.
Pass it an object where each key is the attribute you want to filter and each
value is an array of the filtered values. If you are using OR filters instead
of AND, then just use disjunctiveFacetsRefinements in place of
facetsRefinements.
If you want to filter on an attribute for which you’re not using a widget, you
will have to also pass the facets key to the searchParameters with an array
containing the name of your attribute. Use disjunctiveFacets instead of
facets if you’d like to do an OR instead of an AND. Note that you still
need to add the attribute to the
attributesForFacetting
in your index configuration.
Hide results on init
var search = instantsearch({
[...],
searchFunction: function(helper) {
var searchResults = $('.search-results');
if (helper.state.query === '') {
searchResults.hide();
return;
}
helper.search();
searchResults.show();
}
}
By default, the library will do an empty query ('') on startup and display the
results for this query. If you’d like to display results only when users
actually start typing, you can use the searchFunction hook.
This method takes only one argument, helper, on which you can call .search()
to actually start the search. helper.state also contains information about
the current state of your search.
You can, for example, check for helper.state.query to see if the query is empty
or not, and act accordingly. You might also have to handle the case when users
start typing, then delete their query and hide the results when that happens.
Note that for the sake of brevity, we use a jQuery-like syntax in the example, but any other method to show/hide the results would work.
Community widgets
Community widgets are solving specific use cases and so cannot make it into the core instantsearch.js library.
You may want to create and publish your own community widget, we have a dedicated section on how to create them.
If you want your widget to be listed here, open an issue.
ionRangeSlider
Provides Ion.RangeSlider as a widget. This is a jQuery plugin so you will need to use jQuery in your page.
Widget demo:

See the full documentation.
Templates
// Mustache template example
search.addWidget(
instantsearch.widgets.stats({
container: '#stats',
templates: {
body: '<div>You have {{nbHits}} results, fetched in {{processingTimeMS}}ms.</div>'
}
})
);
// Function template example
search.addWidget(
instantsearch.widgets.stats({
container: '#stats',
templates: {
body: function(data) {
return '<div>You have ' + data.nbHits + ' results, fetched in ' +
data.processingTimeMS +'ms.</div>'
}
}
})
);
Most of the widgets accept a template or templates option that let you change the default rendering. Templates can be defined either as a Mustache string or as a function receiving the widget data and returning either a string or a React element.
See the documentation of each widget to see which data is passed to the template.
Helpers
search.templatesConfig.helpers.emphasis = function(text, render) {
return '<em>' + render(text) + '</em>';
};
In your helper, this always refers to the data
search.templatesConfig.helpers.discount = function(/*text, render*/) {
var discount = this.price * 0.3;
return '$ -' + discount;
};
In order to help you use templates, instantsearch.js exposes a few helpers.
All helpers are accessible in the Mustache templating through {{#helpers.nameOfTheHelper}}{{valueToFormat}}{{/helpers.nameOfTheHelper}}. To use them in the function templates, you’ll have to call search.templatesConfig.helpers.nameOfTheHelper where search is your current instantsearch.js instance.
Currently, we have one helper:
formatNumber: Will accept a number as input and return the formatted version of the number in the locale defined with the numberLocale config option (defaults to en-EN). eg. 100000 will be formatted as 100 000 with en-EN
Options
var search = instantsearch({
appId: '',
apiKey: '',
indexName: '',
templatesConfig: {
compileOptions: {
// all the Hogan compile options
}
}
});
You can configure the options passed to underlying Hogan.compile by using search.templatesConfig.compileOptions. We accept all compile options.
Theses options will be passed to the Hogan.compile calls when you pass a custom template.
Customize
Custom widgets
var customWidget = {
getConfiguration: function(searchParams) {
return {
// see "Usage" tab for more details on the API
};
},
init: function(options) {
// see "Usage" tab for more details on the API
},
// Called every time there is new data
render: function(options) {
// see "Usage" tab for more details on the API
}
};
search.addWidget(customWidget);
search.addWidget(widget)
The widget may implement some of the following methods (depending on the need of the widget):
widget.getConfiguration: Configures the underlying AlgoliaSearch JS helper. Takes a SearchParameters and should return the properties needed as an object.widget.initInitializes the widget (its DOM). Called before the first search. Takes an object with the following keys:- state: the search state.
- helper: the helper used to create a new search query
- templatesConfig: the template configuration
widget.render: Renders the widget after the search results come back from algolia. Takes an object with the following keys:- results: the results of the query
- state: the search state.
- helper: the helper used to create a new search query
- createURL: function provided to create URLs
instantsearch.js was designed with extensibility in mind. You can build your own widget by creating an object that exposes some of those methods:
getConfiguration(): configures the underlying AlgoliaSearch JS Helperinit(): called once after the initializationrender(): called every time we have new search data
You must at least define init or render methods.
jQuery widget
You can use jQuery to power your custom widgets.
To get started, check out our simple boilerplate instantsearch/instantsearch-jQuery-widget.
To wrap an existing jQuery plugin, see our instantsearch/instantsearch-ion.rangeSlider widget.
plain JavaScript widget
You can extend the capabilities of instantsearch.js using plain JavaScript, no need to include any extra dependency.
Have a look at our simple JavaScript example instantsearch/instantsearch-JavaScript-widget to get started.
React widget
A third option for your widgets is React. instantsearch.js is already based on React.
We have a simple commonJS boilerplate: instantsearch/instantsearch-React-widget .
Or you can wrap an existing React component, see our instantsearch/instantsearch-googlemaps example widget.
Custom themes
All widgets have been designed to be heavily stylable with CSS rules. instantsearch.js ships with a default CSS theme that only includes the necessary CSS classes.
You can see all the existing customizable CSS classes in the non-minified CSS.
We use Sass to build the CSS.
We’re also following BEM, a methodology that helps you achieve reusable components and code sharing in the front-end.
If you want to build you own theme, we recommend you to start from our default stylesheet: instantsearch.scss.
BEM modifiers
We’re providing a few SCSS mixins to help you write BEM rules. Those mixins can be loaded from the _base.scss file.
// .ais-<block>--<element>
@include bem(block, element) {
color: red
}
// .ais-<block>--<element>__<modifier>
@include bem(block, element, modifier) {
color: red
}
// .ais-<block>
@include block(block) {
// .ais-<block>--<element>
@include element(element) {
// .ais-<block>--<element>__<modifier>
@include modifier(modifier) {
color: red
}
}
}
Example
If you want to style the search-box widget, you can do:
With SCSS
@import 'base'
@include bem(search-box, input) {
border: 1px solid #A9A9A9;
height: 40px;
padding: 0 8px;
width: 100%;
color: #636363;
}
With CSS
.ais-search-box--input {
border: 1px solid #A9A9A9;
height: 40px;
padding: 0 8px;
width: 100%;
color: #636363;
}