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>

Add widgets

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

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.

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

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.init Initializes 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 Helper
  • init(): called once after the initialization
  • render(): 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;
}