<NME> README.md
<BEF> <p align="center">
  <a href="https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/">
    <img alt="InstantSearch.js" src=".github/banner.png">
  </a>

  <p align="center">
    InstantSearch.js is a JavaScript library for building performant and instant search experiences with <a href="https://www.algolia.com/?utm_source=instantsearch.js&utm_campaign=repository">Algolia</a>.
  </p>
</p>

---

[![Version][version-svg]][package-url]
[![License][license-image]][license-url]
[![Build Status][ci-svg]][ci-url]
[![Pull reminders][pull-reminders-svg]][pull-reminders-url]

InstantSearch.js is a vanilla JavaScript library that lets you create an instant-search result experience using [Algolia][algolia-website]’s search API. It is part of the InstantSearch family:

**InstantSearch.js** | [React InstantSearch][react-instantsearch-github] | [Vue InstantSearch][vue-instantsearch-github] | [Angular InstantSearch][instantsearch-angular-github] | [React InstantSearch Native][react-instantsearch-github] | [InstantSearch Android][instantsearch-android-github] | [InstantSearch iOS][instantsearch-ios-github]

<details>
  <summary><strong>Table of contents</strong></summary>

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [Why](#why)
- [Getting started](#getting-started)
- [Installation](#installation)
  - [TypeScript users](#typescript-users)
- [Documentation](#documentation)
- [Demos](#demos)
- [Playground](#playground)
- [Browser support](#browser-support)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

</details>

## Why

You should be using InstantSearch if you want to:

- Design search experiences with best practices
- Customize your components at will
- Remain independent from external frameworks

## Getting started

Using InstantSearch.js is as simple as adding this JavaScript code to your page:

```javascript
// 1. Instantiate the search
const search = instantsearch({
  indexName: 'instant_search',
  searchClient: algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'),
});

search.addWidgets([
  // 2. Create an interactive search box
  instantsearch.widgets.searchBox({
    container: '#searchbox',
    placeholder: 'Search for products',
  }),

  // 3. Plug the search results into the product container
  instantsearch.widgets.hits({
    container: '#products',
    templates: {
      item: '{{#helpers.highlight}}{ "attribute": "name" }{{/helpers.highlight}}',
    },
  }),

  // 4. Make the brands refinable
  instantsearch.widgets.refinementList({
    container: '#brand',
    attribute: 'brand',
  }),
]);

// 5. Start the search!
search.start();
```

<p align="center">
  <a href="https://codesandbox.io/s/github/algolia/doc-code-samples/tree/master/InstantSearch.js/getting-started" title="Edit on CodeSandbox">
    <img alt="Edit on CodeSandbox" src="https://codesandbox.io/static/img/play-codesandbox.svg">
  </a>
</p>

To learn more about the library, follow the [getting started](https://www.algolia.com/doc/guides/building-search-ui/getting-started/js/) guide or check how to [add it to your own project](https://www.algolia.com/doc/guides/building-search-ui/installation/js/).

## Installation

```sh
npm install instantsearch.js algoliasearch
# or
yarn add instantsearch.js algoliasearch
```

### TypeScript users

To use InstantSearch.js in a TypeScript environment, depending on your [`algoliasearch`](https://github.com/algolia/algoliasearch-client-javascript) version, you need to import different types.

>You still need to import these types even if you don't use InstantSearch.js with [`algoliasearch`](https://github.com/algolia/algoliasearch-client-javascript).

#### `algoliasearch` v4.x

This version uses types provided by both `algoliasearch` and `@algolia/client-search`.

```bash
yarn add algoliasearch@4 @algolia/client-search
```

#### `algoliasearch` v3.x

```bash
yarn add @types/algoliasearch@3
```

>v3.x is deprecated and will soon no longer be supported.

## Documentation

The documentation is available on the [Algolia website](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/).

## Demos

| E-commerce                                                                                                                                                                                                                   | Media                                                                                                                                                                                                         | Travel                                                                                                                                                                                                              |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <a href="https://instantsearchjs.netlify.com/examples/e-commerce/"><img src="https://www.algolia.com/doc/assets/images/build-search-ui/demos/e-commerce-2c7ed6b6.png" width="250" alt="E-commerce demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/media/"><img src="./examples/media/capture.png" width="250" alt="Media demo preview"></a> | <a href="https://instantsearchjs.netlify.com/examples/tourism/"><img src="https://instantsearchjs.netlify.com/examples/tourism/capture.png" width="250" alt="Tourism demo preview"></a> |

See more demos [on the website](https://www.algolia.com/doc/guides/building-search-ui/resources/demos/js/).

## Playground

You can get to know InstantSearch.js on [this playground](https://codesandbox.io/s/github/algolia/create-instantsearch-app/tree/templates/instantsearch.js).

Start by [adding widgets](https://www.algolia.com/doc/guides/building-search-ui/widgets/showcase/js/) and tweaking the display. Once you feel familiar with the library, we recommend following the [getting started guide](https://www.algolia.com/doc/guides/building-search-ui/getting-started/js/).

## Browser support

We support the **last two versions of major browsers** (Chrome, Edge, Firefox, Safari).

Please refer to the [browser support](https://www.algolia.com/doc/guides/building-search-ui/installation/js/#browser-support) section in the documentation to use InstantSearch.js on other browsers.

## Troubleshooting

Encountering an issue? Before reaching out to support, we recommend heading to our [FAQ](https://www.algolia.com/doc/guides/building-search-ui/troubleshooting/faq/js/) where you will find answers for the most common issues and gotchas with the library.

## Contributing

We welcome all contributors, from casual to regular 💙

- **Bug report**. Is something not working as expected? [Send a bug report](https://github.com/algolia/instantsearch.js/issues/new?template=Bug_report.md).
- **Feature request**. Would you like to add something to the library? [Send a feature request](https://github.com/algolia/instantsearch.js/issues/new?template=Feature_request.md).
- **Documentation**. Did you find a typo in the doc? [Open an issue](https://github.com/algolia/instantsearch.js/issues/new) and we'll take care of it.
- **Development**. If you don't know where to start, you can check the open issues that are [tagged easy](https://github.com/algolia/instantsearch.js/issues?q=is%3Aopen+is%3Aissue+label%3A%22Difficulty%3A++++++%E2%9D%84%EF%B8%8F+easy%22), the [bugs](https://github.com/algolia/instantsearch.js/issues?q=is%3Aissue+is%3Aopen+label%3A%22%E2%9D%A4+Bug%22) or [chores](https://github.com/algolia/instantsearch.js/issues?q=is%3Aissue+is%3Aopen+label%3A%22%E2%9C%A8+Chore%22).

To start contributing to code, you need to:

1.  [Fork the project](https://help.github.com/articles/fork-a-repo/)
1.  [Clone the repository](https://help.github.com/articles/cloning-a-repository/)
1.  Install the dependencies: `yarn`
1.  Run the development mode: `yarn start`
1.  [Open the stories](http://localhost:6006)

Please read [our contribution process](CONTRIBUTING.md) to learn more.

## License

InstantSearch.js is [MIT licensed][license-url].

<!-- Badges -->

[version-svg]: https://img.shields.io/npm/v/instantsearch.js.svg?style=flat-square
[package-url]: https://npmjs.org/package/instantsearch.js
[ci-svg]: https://img.shields.io/circleci/project/github/algolia/instantsearch.js.svg?style=flat-square
[ci-url]: https://circleci.com/gh/algolia/instantsearch.js
[pull-reminders-svg]: https://img.shields.io/badge/pull%20reminders-✓-success.svg?style=flat-square
[pull-reminders-url]: https://pullreminders.com?ref=badge
[license-image]: http://img.shields.io/badge/license-MIT-green.svg?style=flat-square
[license-url]: LICENSE

<!-- Links -->

[algolia-website]: https://www.algolia.com/?utm_source=instantsearch.js&utm_campaign=repository
[react-instantsearch-github]: https://github.com/algolia/react-instantsearch/
[vue-instantsearch-github]: https://github.com/algolia/vue-instantsearch
[instantsearch-android-github]: https://github.com/algolia/instantsearch-android
[instantsearch-ios-github]: https://github.com/algolia/instantsearch-ios
[instantsearch-angular-github]: https://github.com/algolia/angular-instantsearch
```js
/**
 * Instantiate a searchbox
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String} [options.placeholder='Search here'] Input's placeholder
 * @param  {Object} [options.cssClass] CSS classes to add to the input
 * @param  {boolean} [poweredBy=false] Show a powered by Algolia link below the input
 * @param  {boolean|string} [autofocus='auto'] autofocus on the input
```js
/**
 * Display various stats about the current search state
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {Object} [options.cssClasses] CSS classes to add
 * @param  {String} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header=''] Header template
 * @param  {String|Function} [options.templates.body] Body template
 * @param  {String|Function} [options.templates.footer=''] Footer template
 * @param  {Function} [options.transformData] Function to change the object passed to the `body` template
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
 * @return {Object}
```js
/**
 * Instantiate a dropdown element to choose the current targeted index
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {Array} options.indices Array of objects defining the different indices to choose from.
 * @param  {String} options.indices[0].name Name of the index to target
 * @param  {String} options.indices[0].label Label displayed in the dropdown
 * @param  {Object} [options.cssClasses] CSS classes to be added
 * @param  {String} [options.cssClasses.root] CSS classes added to the parent <select>
 * @param  {String} [options.cssClasses.item] CSS classes added to each <option>
 * @param  {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
 * @return {Object}
 */
```js
/**
 * Instantiate a dropdown element to choose the number of hits to display per page
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {Array} options.options Array of objects defining the different values and labels
 * @param  {Number} options.options[0].value Number of hits to display per page
 * @param  {String} options.options[0].label Label to display in the option
 * @param  {Object} [options.cssClasses] CSS classes to be added
 * @param  {String} [options.cssClasses.root] CSS classes added to the parent <select>
 * @param  {String} [options.cssClasses.item] CSS classes added to each <option>
 * @param  {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
 * @return {Object}
 */
```js
/**
 * Add a pagination menu to navigate through the results
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String|String[]} [options.cssClass] CSS class to be added to the wrapper element
 * @param  {Object} [options.labels] Text to display in the various links (prev, next, first, last)
 * @param  {String} [options.labels.prev] Label for the Previous link
 * @param  {String} [options.labels.next] Label for the Next link
 * @param  {String} [options.labels.first] Label for the First link
 * @param  {String} [options.labels.last] Label for the Last link
 * @param  {Number} [maxPages=20] The max number of pages to browse
 * @param  {String|DOMElement|boolean} [scrollTo='body'] Where to scroll after a click, set to `false` to disable
 * @param  {boolean} [showFirstLast=true] Define if the First and Last links should be displayed
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
 * @return {Object}
```js
/**
 * Display the list of results (hits) from the current search
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {Object} [options.cssClasses] CSS classes to add
 * @param  {String} [options.cssClasses.root] CSS class to add to the wrapping element
 * @param  {String} [options.cssClasses.empty] CSS class to add to the wrapping element when no results
 * @param  {String} [options.cssClasses.item] CSS class to add to each result
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.empty=''] Template to use when there are no results.
 * @param  {String|Function} [options.templates.item=''] Template to use for each result.
 * @param  {Object} [options.transformData] Method to change the object passed to the templates
 * @param  {Function} [options.transformData.empty=''] Method used to change the object passed to the empty template
 * @param  {Function} [options.transformData.item=''] Method used to change the object passed to the item template
 * @param  {Number} [hitsPerPage=20] The number of hits to display per page
 * @return {Object}
 */
```
 * Instantiate the toggling of a boolean facet filter on and off.
 * Note that it will not toggle between `true` and `false, but between `true`
 * and `undefined`.
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
 * @param  {String} options.label Human-readable name of the filter (eg. "Free Shipping")
 * @param  {Object} [options.cssClasses] CSS classes to add
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
 * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
 * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
 * @param  {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
 * @param  {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
 * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header=''] Header template
 * @param  {String|Function} [options.templates.item] Item template
 * @param  {String|Function} [options.templates.footer=''] Footer template
 * @param  {Function} [options.transformData] Function to change the object passed to the item template
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
 * @return {Object}
```js
/**
 * Instantiate a list of refinements based on a facet
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String} options.facetName Name of the attribute for faceting
 * @param  {String} [options.operator='or'] How to apply refinements. Possible values: `or`, `and`
 * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
 * @param  {String} [options.limit=1000] How much facet values to get
 * @param  {Object} [options.cssClasses] CSS classes to add
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
 * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
 * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
 * @param  {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
 * @param  {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
 * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header] Header template
 * @param  {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
 * @param  {String|Function} [options.templates.footer] Footer template
 * @param  {Function} [options.transformData] Function to change the object passed to the item template
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
 * @return {Object}
```js
/**
 * Create a menu out of a facet
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String} options.facetName Name of the attribute for faceting
 * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
 * @param  {String} [options.limit=100] How many facets values to retrieve
 * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
 * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
 * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
 * @param  {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
 * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header=''] Header template
 * @param  {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
 * @param  {String|Function} [options.templates.footer=''] Footer template
 * @param  {Function} [options.transformData] Method to change the object passed to the item template
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
 * @return {Object}
```js
/**
 * Instantiate a slider based on a numeric attribute
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String} options.facetName Name of the attribute for faceting
 * @param  {Boolean|Object} [options.tooltips=true] Should we show tooltips or not.
 * The default tooltip will show the formatted corresponding value without any other token.
 * You can also provide
 * tooltips: {format: function(formattedValue, rawValue) {return '$' + formattedValue}}
 * So that you can format the tooltip display value as you want
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header=''] Header template
 * @param  {String|Function} [options.templates.footer=''] Footer template
 * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, body
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
 * @return {Object}
 */
```js
/**
 * Instantiate a price ranges on a numerical facet
 * @param  {String|DOMElement} options.container Valid CSS Selector as a string or DOMElement
 * @param  {String} options.facetName Name of the attribute for faceting
 * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, range
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String|String[]} [options.cssClasses.range] CSS class to add to the range element
 * @param  {String|String[]} [options.cssClasses.input] CSS class to add to the min/max input elements
 * @param  {String|String[]} [options.cssClasses.button] CSS class to add to the button element
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.range] Range template
 * @param  {Object} [options.labels] Labels to use for the widget
 * @param  {String|Function} [options.labels.button] Button label
 * @param  {String|Function} [options.labels.currency] Currency label
 * @param  {String|Function} [options.labels.to] To label
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
 * @return {Object}
 */
```js
/**
 * Create a hierarchical menu using multiple attributes
 * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
 * @param  {String[]} options.attributes Array of attributes to use to generate the hierarchy of the menu.
 * You need to follow some conventions:
 * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
 * @param  {Number} [options.limit=100] How much facet values to get
 * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
 * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
 * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
 * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
 * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
 * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
 * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
 * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
 * @param  {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
 * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
 * @param  {Object} [options.templates] Templates to use for the widget
 * @param  {String|Function} [options.templates.header=''] Header template (root level only)
 * @param  {String|Function} [options.templates.item] Item template
 * @param  {String|Function} [options.templates.footer=''] Footer template (root level only)
 * @param  {Function} [options.transformData] Method to change the object passed to the item template
 * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
 * @return {Object}

<MSG> docs(widgets): Use primitive types instead of wrappers

Closes #153

<DFF> @@ -320,8 +320,8 @@ instantsearch({
 ```js
 /**
  * Instantiate a searchbox
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String} [options.placeholder='Search here'] Input's placeholder
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string} [options.placeholder='Search here'] Input's placeholder
  * @param  {Object} [options.cssClass] CSS classes to add to the input
  * @param  {boolean} [poweredBy=false] Show a powered by Algolia link below the input
  * @param  {boolean|string} [autofocus='auto'] autofocus on the input
@@ -376,17 +376,17 @@ search.addWidget(
 ```js
 /**
  * Display various stats about the current search state
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
  * @param  {Object} [options.cssClasses] CSS classes to add
- * @param  {String} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
+ * @param  {string} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header=''] Header template
- * @param  {String|Function} [options.templates.body] Body template
- * @param  {String|Function} [options.templates.footer=''] Footer template
+ * @param  {string|Function} [options.templates.header=''] Header template
+ * @param  {string|Function} [options.templates.body] Body template
+ * @param  {string|Function} [options.templates.footer=''] Footer template
  * @param  {Function} [options.transformData] Function to change the object passed to the `body` template
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
  * @return {Object}
@@ -450,13 +450,13 @@ you'll need several indices. This widget lets you easily change it.
 ```js
 /**
  * Instantiate a dropdown element to choose the current targeted index
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
  * @param  {Array} options.indices Array of objects defining the different indices to choose from.
- * @param  {String} options.indices[0].name Name of the index to target
- * @param  {String} options.indices[0].label Label displayed in the dropdown
+ * @param  {string} options.indices[0].name Name of the index to target
+ * @param  {string} options.indices[0].label Label displayed in the dropdown
  * @param  {Object} [options.cssClasses] CSS classes to be added
- * @param  {String} [options.cssClasses.root] CSS classes added to the parent <select>
- * @param  {String} [options.cssClasses.item] CSS classes added to each <option>
+ * @param  {string} [options.cssClasses.root] CSS classes added to the parent <select>
+ * @param  {string} [options.cssClasses.item] CSS classes added to each <option>
  * @param  {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
  * @return {Object}
  */
@@ -513,13 +513,13 @@ displayed per page.
 ```js
 /**
  * Instantiate a dropdown element to choose the number of hits to display per page
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
  * @param  {Array} options.options Array of objects defining the different values and labels
- * @param  {Number} options.options[0].value Number of hits to display per page
- * @param  {String} options.options[0].label Label to display in the option
+ * @param  {number} options.options[0].value number of hits to display per page
+ * @param  {string} options.options[0].label Label to display in the option
  * @param  {Object} [options.cssClasses] CSS classes to be added
- * @param  {String} [options.cssClasses.root] CSS classes added to the parent <select>
- * @param  {String} [options.cssClasses.item] CSS classes added to each <option>
+ * @param  {string} [options.cssClasses.root] CSS classes added to the parent <select>
+ * @param  {string} [options.cssClasses.item] CSS classes added to each <option>
  * @param  {boolean} [hideContainerWhenNoResults=false] Hide the container when no results match
  * @return {Object}
  */
@@ -573,15 +573,15 @@ search.addWidget(
 ```js
 /**
  * Add a pagination menu to navigate through the results
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String|String[]} [options.cssClass] CSS class to be added to the wrapper element
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string|string[]} [options.cssClass] CSS class to be added to the wrapper element
  * @param  {Object} [options.labels] Text to display in the various links (prev, next, first, last)
- * @param  {String} [options.labels.prev] Label for the Previous link
- * @param  {String} [options.labels.next] Label for the Next link
- * @param  {String} [options.labels.first] Label for the First link
- * @param  {String} [options.labels.last] Label for the Last link
- * @param  {Number} [maxPages=20] The max number of pages to browse
- * @param  {String|DOMElement|boolean} [scrollTo='body'] Where to scroll after a click, set to `false` to disable
+ * @param  {string} [options.labels.prev] Label for the Previous link
+ * @param  {string} [options.labels.next] Label for the Next link
+ * @param  {string} [options.labels.first] Label for the First link
+ * @param  {string} [options.labels.last] Label for the Last link
+ * @param  {number} [maxPages=20] The max number of pages to browse
+ * @param  {string|DOMElement|boolean} [scrollTo='body'] Where to scroll after a click, set to `false` to disable
  * @param  {boolean} [showFirstLast=true] Define if the First and Last links should be displayed
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
  * @return {Object}
@@ -620,18 +620,18 @@ search.addWidget(
 ```js
 /**
  * Display the list of results (hits) from the current search
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
  * @param  {Object} [options.cssClasses] CSS classes to add
- * @param  {String} [options.cssClasses.root] CSS class to add to the wrapping element
- * @param  {String} [options.cssClasses.empty] CSS class to add to the wrapping element when no results
- * @param  {String} [options.cssClasses.item] CSS class to add to each result
+ * @param  {string} [options.cssClasses.root] CSS class to add to the wrapping element
+ * @param  {string} [options.cssClasses.empty] CSS class to add to the wrapping element when no results
+ * @param  {string} [options.cssClasses.item] CSS class to add to each result
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.empty=''] Template to use when there are no results.
- * @param  {String|Function} [options.templates.item=''] Template to use for each result.
+ * @param  {string|Function} [options.templates.empty=''] Template to use when there are no results.
+ * @param  {string|Function} [options.templates.item=''] Template to use for each result.
  * @param  {Object} [options.transformData] Method to change the object passed to the templates
  * @param  {Function} [options.transformData.empty=''] Method used to change the object passed to the empty template
  * @param  {Function} [options.transformData.item=''] Method used to change the object passed to the item template
- * @param  {Number} [hitsPerPage=20] The number of hits to display per page
+ * @param  {number} [hitsPerPage=20] The number of hits to display per page
  * @return {Object}
  */
 ```
@@ -706,24 +706,24 @@ Note that we are not toggling from `true` to `false` here, but from `true` to
  * Instantiate the toggling of a boolean facet filter on and off.
  * Note that it will not toggle between `true` and `false, but between `true`
  * and `undefined`.
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
- * @param  {String} options.label Human-readable name of the filter (eg. "Free Shipping")
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string} options.facetName Name of the attribute for faceting (eg. "free_shipping")
+ * @param  {string} options.label Human-readable name of the filter (eg. "Free Shipping")
  * @param  {Object} [options.cssClasses] CSS classes to add
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
- * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
- * @param  {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
- * @param  {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
- * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string|string[]} [options.cssClasses.list] CSS class to add to the list element
+ * @param  {string|string[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param  {string|string[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param  {string|string[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header=''] Header template
- * @param  {String|Function} [options.templates.item] Item template
- * @param  {String|Function} [options.templates.footer=''] Footer template
+ * @param  {string|Function} [options.templates.header=''] Header template
+ * @param  {string|Function} [options.templates.item] Item template
+ * @param  {string|Function} [options.templates.footer=''] Footer template
  * @param  {Function} [options.transformData] Function to change the object passed to the item template
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
  * @return {Object}
@@ -799,26 +799,26 @@ search.addWidget(
 ```js
 /**
  * Instantiate a list of refinements based on a facet
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String} options.facetName Name of the attribute for faceting
- * @param  {String} [options.operator='or'] How to apply refinements. Possible values: `or`, `and`
- * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
- * @param  {String} [options.limit=1000] How much facet values to get
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string} options.facetName Name of the attribute for faceting
+ * @param  {string} [options.operator='or'] How to apply refinements. Possible values: `or`, `and`
+ * @param  {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
+ * @param  {string} [options.limit=1000] How much facet values to get
  * @param  {Object} [options.cssClasses] CSS classes to add
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
- * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
- * @param  {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
- * @param  {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
- * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string|string[]} [options.cssClasses.list] CSS class to add to the list element
+ * @param  {string|string[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param  {string|string[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param  {string|string[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header] Header template
- * @param  {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
- * @param  {String|Function} [options.templates.footer] Footer template
+ * @param  {string|Function} [options.templates.header] Header template
+ * @param  {string|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
+ * @param  {string|Function} [options.templates.footer] Footer template
  * @param  {Function} [options.transformData] Function to change the object passed to the item template
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
  * @return {Object}
@@ -897,24 +897,24 @@ search.addWidget(
 ```js
 /**
  * Create a menu out of a facet
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String} options.facetName Name of the attribute for faceting
- * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
- * @param  {String} [options.limit=100] How many facets values to retrieve
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string} options.facetName Name of the attribute for faceting
+ * @param  {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
+ * @param  {string} [options.limit=100] How many facets values to retrieve
  * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
- * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
- * @param  {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
- * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string|string[]} [options.cssClasses.list] CSS class to add to the list element
+ * @param  {string|string[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param  {string|string[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param  {string|string[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header=''] Header template
- * @param  {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
- * @param  {String|Function} [options.templates.footer=''] Footer template
+ * @param  {string|Function} [options.templates.header=''] Header template
+ * @param  {string|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
+ * @param  {string|Function} [options.templates.footer=''] Footer template
  * @param  {Function} [options.transformData] Method to change the object passed to the item template
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
  * @return {Object}
@@ -992,19 +992,19 @@ search.addWidget(
 ```js
 /**
  * Instantiate a slider based on a numeric attribute
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String} options.facetName Name of the attribute for faceting
- * @param  {Boolean|Object} [options.tooltips=true] Should we show tooltips or not.
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string} options.facetName Name of the attribute for faceting
+ * @param  {boolean|Object} [options.tooltips=true] Should we show tooltips or not.
  * The default tooltip will show the formatted corresponding value without any other token.
  * You can also provide
  * tooltips: {format: function(formattedValue, rawValue) {return '$' + formattedValue}}
  * So that you can format the tooltip display value as you want
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header=''] Header template
- * @param  {String|Function} [options.templates.footer=''] Footer template
+ * @param  {string|Function} [options.templates.header=''] Header template
+ * @param  {string|Function} [options.templates.footer=''] Footer template
  * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, body
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
  * @return {Object}
  */
@@ -1039,22 +1039,22 @@ search.addWidget(
 ```js
 /**
  * Instantiate a price ranges on a numerical facet
- * @param  {String|DOMElement} options.container Valid CSS Selector as a string or DOMElement
- * @param  {String} options.facetName Name of the attribute for faceting
+ * @param  {string|DOMElement} options.container Valid CSS Selector as a string or DOMElement
+ * @param  {string} options.facetName Name of the attribute for faceting
  * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, range
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String|String[]} [options.cssClasses.range] CSS class to add to the range element
- * @param  {String|String[]} [options.cssClasses.input] CSS class to add to the min/max input elements
- * @param  {String|String[]} [options.cssClasses.button] CSS class to add to the button element
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string|string[]} [options.cssClasses.range] CSS class to add to the range element
+ * @param  {string|string[]} [options.cssClasses.input] CSS class to add to the min/max input elements
+ * @param  {string|string[]} [options.cssClasses.button] CSS class to add to the button element
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.range] Range template
+ * @param  {string|Function} [options.templates.range] Range template
  * @param  {Object} [options.labels] Labels to use for the widget
- * @param  {String|Function} [options.labels.button] Button label
- * @param  {String|Function} [options.labels.currency] Currency label
- * @param  {String|Function} [options.labels.to] To label
+ * @param  {string|Function} [options.labels.button] Button label
+ * @param  {string|Function} [options.labels.currency] Currency label
+ * @param  {string|Function} [options.labels.to] To label
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when no results match
  * @return {Object}
  */
@@ -1090,25 +1090,25 @@ search.addWidget(
 ```js
 /**
  * Create a hierarchical menu using multiple attributes
- * @param  {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param  {String[]} options.attributes Array of attributes to use to generate the hierarchy of the menu.
+ * @param  {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
+ * @param  {string[]} options.attributes Array of attributes to use to generate the hierarchy of the menu.
  * You need to follow some conventions:
- * @param  {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
- * @param  {Number} [options.limit=100] How much facet values to get
+ * @param  {string[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
+ * @param  {number} [options.limit=100] How much facet values to get
  * @param  {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
- * @param  {String|String[]} [options.cssClasses.root] CSS class to add to the root element
- * @param  {String|String[]} [options.cssClasses.header] CSS class to add to the header element
- * @param  {String|String[]} [options.cssClasses.body] CSS class to add to the body element
- * @param  {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
- * @param  {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param  {String|String[]} [options.cssClasses.item] CSS class to add to each item element
- * @param  {String|String[]} [options.cssClasses.active] CSS class to add to each active element
- * @param  {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
- * @param  {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.root] CSS class to add to the root element
+ * @param  {string|string[]} [options.cssClasses.header] CSS class to add to the header element
+ * @param  {string|string[]} [options.cssClasses.body] CSS class to add to the body element
+ * @param  {string|string[]} [options.cssClasses.footer] CSS class to add to the footer element
+ * @param  {string|string[]} [options.cssClasses.list] CSS class to add to the list element
+ * @param  {string|string[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param  {string|string[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param  {string|string[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
+ * @param  {string|string[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
  * @param  {Object} [options.templates] Templates to use for the widget
- * @param  {String|Function} [options.templates.header=''] Header template (root level only)
- * @param  {String|Function} [options.templates.item] Item template
- * @param  {String|Function} [options.templates.footer=''] Footer template (root level only)
+ * @param  {string|Function} [options.templates.header=''] Header template (root level only)
+ * @param  {string|Function} [options.templates.item] Item template
+ * @param  {string|Function} [options.templates.footer=''] Footer template (root level only)
  * @param  {Function} [options.transformData] Method to change the object passed to the item template
  * @param  {boolean} [hideContainerWhenNoResults=true] Hide the container when there's no results
  * @return {Object}

{'addition_count': 122, 'commit_subject': 'docs(widgets): Use primitive types instead of wrappers', 'deletion_count': 122, 'file_extension': '.md', 'lang': 'md', 'license': 'mit', 'repo_name': 'algolia/instantsearch.js'}