Gathering detailed insights and metrics for algoliasearch-helper
Gathering detailed insights and metrics for algoliasearch-helper
Gathering detailed insights and metrics for algoliasearch-helper
Gathering detailed insights and metrics for algoliasearch-helper
@types/algoliasearch-helper
Stub TypeScript definitions entry for algoliasearch-helper, which provides its own types definitions
react-algoliasearch-helper
React `<Provider helper>` and `connect()(WrappedComponent)` for algoliasearch-helper
react-algoliasearch-helper-vl
React `<Provider helper>` and `connect()(WrappedComponent)` for algoliasearch-helper
algoliasearch-helper-mc
Helper for implementing advanced search features with algolia
⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
npm install algoliasearch-helper
Typescript
Module System
Node Version
NPM Version
98
Supply Chain
93
Quality
89.1
Maintenance
100
Vulnerability
100
License
react-instantsearch@7.16.2
Updated on Jul 22, 2025
react-instantsearch-router-nextjs@7.16.2
Updated on Jul 22, 2025
react-instantsearch-nextjs@1.0.1
Updated on Jul 22, 2025
vue-instantsearch@4.21.2
Updated on Jul 22, 2025
react-instantsearch-core@7.16.2
Updated on Jul 22, 2025
algolia-experiences@1.5.14
Updated on Jul 22, 2025
TypeScript (76.43%)
JavaScript (19.33%)
SCSS (1.38%)
Vue (1.37%)
Handlebars (0.64%)
CSS (0.24%)
Astro (0.19%)
Pug (0.19%)
HTML (0.08%)
Swift (0.08%)
Java (0.03%)
Shell (0.03%)
Total Downloads
148,111,778
Last Day
55,681
Last Week
1,081,281
Last Month
4,763,544
Last Year
45,930,237
MIT License
3,905 Stars
11,522 Commits
543 Forks
131 Watchers
106 Branches
391 Contributors
Updated on Jul 30, 2025
Latest Version
3.26.0
Package Id
algoliasearch-helper@3.26.0
Unpacked Size
1.10 MB
Size
223.60 kB
File Count
38
NPM Version
lerna/6.0.3/node@v20.10.0+x64 (linux)
Node Version
20.10.0
Published on
Jun 16, 2025
Cumulative downloads
Total Downloads
Last Day
6.4%
55,681
Compared to previous day
Last Week
-1.8%
1,081,281
Compared to previous week
Last Month
2.3%
4,763,544
Compared to previous month
Last Year
26.8%
45,930,237
Compared to previous year
Coming from V1 (or js client v2)? Read the migration guide to the new version of the Helper.
Coming from V2? Read the migration guide to the new version of the Helper.
The JavaScript helper is an advanced library we provide to our users. If you are looking to build a complete search interface, we recommend you to use InstantSearch. If you want to build an autocomplete menu, see Autocomplete.
This module is the companion of the algolia/algoliasearch-client-javascript. It helps you keep track of the search parameters and provides a higher level API.
A small example that uses Browserify to manage modules.
1var algoliasearch = require('algoliasearch'); 2var algoliasearchHelper = require('algoliasearch-helper'); 3 4var client = algoliasearch('appId', 'apiKey'); 5 6var helper = algoliasearchHelper(client, 'indexName', { 7 facets: ['mainCharacterFirstName', 'year'], 8 disjunctiveFacets: ['director'], 9}); 10 11helper.on('result', function (event) { 12 console.log(event.results); 13}); 14 15helper.addDisjunctiveFacetRefinement('director', 'Clint Eastwood'); 16helper.addDisjunctiveFacetRefinement('director', 'Sofia Coppola'); 17 18helper.addNumericRefinement('year', '=', 2003); 19 20// Search for any movie filmed in 2003 and directed by either C. Eastwood or S. Coppola 21helper.search();
See more examples in the examples folder
1<script src="https://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.angular.js"></script> 2<script src="dist/algoliasearch.helper.min.js"></script> 3 4<script type="text/javascript"> 5angular.module('searchApp', ['ngSanitize', 'algoliasearch']) 6.controller('searchController', ['$scope', '$sce', 'algolia', function($scope, $sce, algolia) { 7 var algolia = algolia.Client('applicationId', 'apiKey'); 8 $scope.q = ''; 9 $scope.content = null; 10 $scope.helper = algoliasearchHelper(algolia, 'indexName', { 11 facets: ['type', 'shipping'], 12 disjunctiveFacets: ['category', 'manufacturer'], 13 hitsPerPage: 5, 14 }); 15 $scope.helper.on('result', function(event) { 16 $scope.$apply(function() { 17 $scope.content = event.results; 18 }); 19 }); 20 $scope.toggleRefine = function($event, facet, value) { 21 $event.preventDefault(); 22 $scope.helper.toggleRefine(facet, value).search(); 23 }; 24 $scope.$watch('q', function(q) { 25 $scope.helper.setQuery(q).search(); 26 }); 27 $scope.helper.search(); 28}]); 29</script>
You can see the full Angular example here
There is also a complete JSDoc
<script>
tagUse our jsDelivr build:
<script src="https://cdn.jsdelivr.net/algoliasearch.helper/2/algoliasearch.helper.min.js"></script>
npm install algoliasearch-helper
1var helper = algoliasearchHelper(client, 'indexName' /*, parameters*/);
modify the parameters of the search (usually through user interactions)
helper.setQuery('iphone').addFacetRefinement('category', 'phone')
trigger the search (after all the modification have been applied)
helper.search()
read the results (with the event "result" handler) and update the UI with the results
helper.on('result', function(event) { updateUI(event.results); });
go back to 1
AlgoliasearchHelper: the helper. Keeps the state of the search, makes the queries and calls the handlers when an event happen.
SearchParameters: the object representing the state of the search. The current state is stored in helperInstance.state
.
SearchResults: the object in which the Algolia answers are transformed into. This object is passed to the result event handler. An example of SearchResults in JSON is available at the end of this readme
The search is triggered by the search()
method.
It takes all the previous modifications to the search and uses them to create the queries to Algolia. The search parameters are immutable.
Example:
1var helper = algoliasearchHelper(client, indexName); 2 3// Let's monitor the results with the console 4helper.on('result', function (event) { 5 console.log(event.results); 6}); 7 8// Let's make an empty search 9// The results are all sorted using the dashboard configuration 10helper.search(); 11 12// Let's search for "landscape" 13helper.setQuery('landscape').search(); 14 15// Let's add a category "photo" 16// Will make a search with "photo" tag and "landscape" as the query 17helper.addTag('photo').search();
The helper is a Node.js EventEmitter instance.
result
: get notified when new results are received. The handler function will receive two objects (SearchResults
and SearchParameters
).
error
: get notified when errors are received from the API.
change
: get notified when a property has changed in the helper
search
: get notified when a request is sent to Algolia
result
event1helper.on('result', updateTheResults);
result
event once1helper.once('result', updateTheResults);
result
listener1helper.removeListener('result', updateTheResults);
result
listeners1helper.removeAllListeners('result');
All the methods from Node.js EventEmitter class are available.
1helper.setQuery('fruit').search();
Facets are filters to retrieve a subset of an index having a specific value for a given attribute. First you need to define which attribute will be used as a facet in the dashboard: https://www.algolia.com/explorer#?tab=display
Refinements are ANDed by default (Conjunctive selection).
1var helper = algoliasearchHelper(client, indexName, { 2 facets: ['ANDFacet'], 3});
1helper.addFacetRefinement('ANDFacet', 'valueOfANDFacet').search();
1helper.removeFacetRefinement('ANDFacet', 'valueOfANDFacet').search();
Refinements are ORed by default (Disjunctive selection).
1var helper = algoliasearchHelper(client, indexName, { 2 disjunctiveFacets: ['ORFacet'], 3});
1helper.addDisjunctiveFacetRefinement('ORFacet', 'valueOfORFacet').search();
1helper.removeDisjunctiveFacetRefinement('ORFacet', 'valueOfORFacet').search();
Filter so that we do NOT get a given facet
1var helper = algoliasearchHelper(client, indexName, { 2 facets: ['ANDFacet'], 3}).search();
1helper.addFacetExclusion('ANDFacet', 'valueOfANDFacetToExclude');
1helper.removeFacetExclusion('ANDFacet', 'valueOfANDFacetToExclude');
Filter over numeric attributes with math operations like =
, >
, <
, >=
, <=
. Can be used for numbers and dates (if converted to timestamp)
1var helper = algoliasearchHelper(client, indexName, {
2 disjunctiveFacets: ['numericAttribute'],
3});
1helper.addNumericRefinement('numericAttribute', '=', '3').search(); 2// filter to only the results that match numericAttribute=3 3helper.addNumericRefinement('numericAttribute', '=', '4').search(); 4// filter to only the results that match numericAttribute=3 AND numericAttribute=4 5 6// On another numeric with no previous filter 7helper 8 .addNumericRefinement('numericAttribute2', '=', ['42', '56', '37']) 9 .search(); 10// filter to only the results that match numericAttribute2=42 OR numericAttribute2=56 OR numericAttribute2=37
1helper.removeNumericRefinement('numericAttribute', '=', '3').search();
1// for the single operator = on numericAttribute 2helper.removeNumericRefinement('numericAttribute', '=').search(); 3// for all the refinements on numericAttribute 4helper.removeNumericRefinement('numericAttribute').search();
Hierarchical facets are useful to build such navigation menus:
1| products 2 > fruits 3 > citrus 4 | strawberries 5 | peaches 6 | apples
Here, we refined the search this way:
To build such menu, you need to use hierarchical faceting:
1var helper = algoliasearchHelper(client, indexName, { 2 hierarchicalFacets: [ 3 { 4 name: 'products', 5 attributes: ['categories.lvl0', 'categories.lvl1'], 6 }, 7 ], 8});
Requirements: All the specified attributes
must be defined in your Algolia settings as attributes for faceting.
Given your objects looks like this:
1{ 2 "objectID": "123", 3 "name": "orange", 4 "categories": { 5 "lvl0": "fruits", 6 "lvl1": "fruits > citrus" 7 } 8}
And you refine products
:
1helper.toggleFacetRefinement('products', 'fruits > citrus');
You will get a hierarchical presentation of your facet values: a navigation menu of your facet values.
1helper.on('result', function (event) { 2 console.log(event.results.hierarchicalFacets[0]); 3 // { 4 // 'name': 'products', 5 // 'count': null, 6 // 'isRefined': true, 7 // 'path': null, 8 // 'data': [{ 9 // 'name': 'fruits', 10 // 'path': 'fruits', 11 // 'count': 1, 12 // 'isRefined': true, 13 // 'data': [{ 14 // 'name': 'citrus', 15 // 'path': 'fruits > citrus', 16 // 'count': 1, 17 // 'isRefined': true, 18 // 'data': null 19 // }] 20 // }] 21 // } 22});
To ease navigation, we always:
fruits > citrus > *
: n + 1)fruits > citrus
=> fruits
: n -1) categoriesYour records can also share multiple categories between one another by using arrays inside your object:
1{ 2 "objectID": "123", 3 "name": "orange", 4 "categories": { 5 "lvl0": ["fruits", "color"], 6 "lvl1": ["fruits > citrus", "color > orange"] 7 } 8}, 9{ 10 "objectID": "456", 11 "name": "grapefruit", 12 "categories": { 13 "lvl0": ["fruits", "color", "new"], 14 "lvl1": ["fruits > citrus", "color > yellow", "new > citrus"] 15 } 16}
1var helper = algoliasearchHelper(client, indexName, {
2 hierarchicalFacets: [
3 {
4 name: 'products',
5 attributes: ['categories.lvl0', 'categories.lvl1'],
6 separator: '|',
7 },
8 ],
9});
10
11helper.toggleFacetRefinement('products', 'fruits|citrus');
Would mean that your objects look like so:
1{ 2 "objectID": "123", 3 "name": "orange", 4 "categories": { 5 "lvl0": "fruits", 6 "lvl1": "fruits|citrus" 7 } 8}
The default sort for the hierarchical facet view is: isRefined:desc (first show refined), name:asc (then sort by name)
.
You can specify a different sort order by using:
1var helper = algoliasearchHelper(client, indexName, {
2 hierarchicalFacets: [
3 {
4 name: 'products',
5 attributes: ['categories.lvl0', 'categories.lvl1'],
6 sortBy: ['count:desc', 'name:asc'], // first show the most common values, then sort by name
7 },
8 ],
9});
The available sort tokens are:
Let's say you have a lot of levels:
- fruits
- yellow
- citrus
- spicy
But you only want to get the values starting at "citrus", you can use rootPath
You can specify an root path to filter the hierarchical values
var helper = algoliasearchHelper(client, indexName, {
hierarchicalFacets: [{
name: 'products',
attributes: ['categories.lvl0', 'categories.lvl1', 'categories.lvl2', 'categories.lvl3'],
rootPath: 'fruits > yellow > citrus'
}]
});
Having a rootPath will refine the results on it automatically.
By default the hierarchical facet is going to return the child and parent facet values of the current refinement.
If you do not want to get the parent facet values you can set showParentLevel to false
1var helper = algoliasearchHelper(client, indexName, { 2 hierarchicalFacets: [ 3 { 4 name: 'products', 5 attributes: ['categories.lvl0', 'categories.lvl1'], 6 showParentLevel: false, 7 }, 8 ], 9});
1var helper = algoliasearchHelper(client, indexName, { 2 hierarchicalFacets: [ 3 { 4 name: 'products', 5 attributes: ['categories.lvl0', 'categories.lvl1'], 6 separator: '|', 7 }, 8 ], 9}); 10 11helper.toggleFacetRefinement('products', 'fruits|citrus'); 12var breadcrumb = helper.getHierarchicalFacetBreadcrumb('products'); 13 14console.log(breadcrumb); 15// ['fruits', 'citrus'] 16 17console.log(breadcrumb.join(' | ')); 18// 'fruits | citrus'
1helper.clearRefinements().search();
1helper.clearRefinements('ANDFacet').search();
1helper 2 .clearRefinements(function (value, attribute, type) { 3 return type === 'exclude' && attribute === 'ANDFacet'; 4 }) 5 .search();
1helper.on('result', function (event) { 2 // Get the facet values for the attribute age 3 event.results.getFacetValues('age'); 4 // It will be ordered : 5 // - refined facets first 6 // - then ordered by number of occurence (bigger count -> higher in the list) 7 // - then ordered by name (alphabetically) 8});
1helper.on('result', function (event) { 2 // Get the facet values for the attribute age 3 event.results.getFacetValues('age', { sortBy: ['count:asc'] }); 4 // It will be ordered by number of occurence (lower number => higher position) 5 // Elements that can be sorted : count, name, isRefined 6 // Type of sort : 'asc' for ascending order, 'desc' for descending order 7});
This only apply on numeric based facets/attributes.
1helper.on('result', function (event) { 2 // Get the facet values for the attribute age 3 event.results.getFacetStats('age'); 4});
Tags are an easy way to do filtering. They are based on a special attribute in the records named _tags
, which can be a single string value or an array of strings.
1helper.addTag('landscape').search();
1helper.removeTag('landscape').search();
1helper.clearTags().search();
1helper.getPage();
1helper.setPage(3).search();
During a search, changing the parameters will update the result set, which can then change the number of pages in the result set. Therefore, the behavior has been standardized so that any operation that may change the number of page will reset the pagination to page 0.
This may lead to some unexpected behavior. For example:
1helper.setPage(4); 2helper.getPage(); // 4 3helper.setQuery('foo'); 4helper.getPage(); // 0
Non exhaustive list of operations that trigger a reset:
Index can be changed. The common use case is when you have several slaves with different sort order (sort by relevance, price or any other attribute).
1helper.setIndex('index_orderByPrice').search();
1var currentIndex = helper.getIndex();
Sometime it's convenient to reuse the current search parameters with small changes without changing the state stored in the helper. That's why there is a function called searchOnce
. This method does not trigger change
or error
events.
In the following, we are using searchOnce
to fetch only a single element using all the other parameters already set in the search parameters.
1var state = helper.searchOnce( 2 { hitsPerPage: 1 }, 3 function (error, content, state) { 4 // if an error occured it will be passed in error, otherwise its value is null 5 // content contains the results formatted as a SearchResults 6 // state is the instance of SearchParameters used for this search 7 } 8);
1var state1 = helper.searchOnce({ hitsPerPage: 1 }).then(function (res) { 2 // res contains 3 // { 4 // content : SearchResults 5 // state : SearchParameters (the one used for this specific search) 6 // } 7});
There are lots of other parameters you can set.
1var helper = algoliasearchHelper(client, indexName, {
2 hitsPerPage: 50,
3});
1helper.setQueryParameter('hitsPerPage', 20).search();
Name |
Type |
Description |
advancedSyntax |
boolean |
Enable the advanced syntax. |
allowTyposOnNumericTokens |
boolean |
Should the engine allow typos on numerics. |
analytics |
boolean |
Enable the analytics |
analyticsTags |
string |
Tag of the query in the analytics. |
aroundLatLng |
string |
Center of the geo search. |
aroundLatLngViaIP |
boolean |
Center of the search, retrieve from the user IP. |
aroundPrecision |
number |
Precision of the geo search. |
aroundRadius |
number |
Radius of the geo search. |
minimumAroundRadius |
number |
Minimum radius of the geo search. |
attributesToHighlight |
string |
List of attributes to highlight |
attributesToRetrieve |
string |
List of attributes to retrieve |
attributesToSnippet |
string |
List of attributes to snippet |
disjunctiveFacets |
Array.<string> |
All the declared disjunctive facets |
distinct |
boolean|number |
Remove duplicates based on the index setting attributeForDistinct |
facets |
Array.<string> |
All the facets that will be requested to the server |
filters |
string |
Add filters to the query (similar to WHERE clauses) |
getRankingInfo |
integer |
Enable the ranking informations in the response |
hitsPerPage |
number |
Number of hits to be returned by the search API |
ignorePlurals |
boolean |
Should the plurals be ignored |
insideBoundingBox |
string |
Geo search inside a box. |
insidePolygon |
string |
Geo search inside a polygon. |
maxValuesPerFacet |
number |
Number of values for each facetted attribute |
minWordSizefor1Typo |
number |
Number of characters to wait before doing one character replacement. |
minWordSizefor2Typos |
number |
Number of characters to wait before doing a second character replacement. |
optionalWords |
string |
Add some optional words to those defined in the dashboard |
page |
number |
The current page number |
query |
string |
Query string of the instant search. The empty string is a valid query. |
queryType |
string |
How the query should be treated by the search engine. Possible values: prefixAll, prefixLast, prefixNone |
removeWordsIfNoResults |
string |
Possible values are "lastWords" "firstWords" "allOptional" "none" (default) |
replaceSynonymsInHighlight |
boolean |
Should the engine replace the synonyms in the highlighted results. |
restrictSearchableAttributes |
string |
Restrict which attribute is searched. |
synonyms |
boolean |
Enable the synonyms |
tagFilters |
string |
Contains the tag filters in the raw format of the Algolia API. Setting this parameter is not compatible with the of the add/remove/toggle methods of the tag api. |
typoTolerance |
string |
How the typo tolerance behave in the search engine. Possible values: true, false, min, strict |
Here is an example of a result object you get with the result
event.
1{ 2 "hitsPerPage": 10, 3 "processingTimeMS": 2, 4 "facets": [ 5 { 6 "name": "type", 7 "data": { 8 "HardGood": 6627, 9 "BlackTie": 550, 10 "Music": 665, 11 "Software": 131, 12 "Game": 456, 13 "Movie": 1571 14 }, 15 "exhaustive": false 16 }, 17 { 18 "exhaustive": false, 19 "data": { 20 "Free shipping": 5507 21 }, 22 "name": "shipping" 23 } 24 ], 25 "hits": [ 26 { 27 "thumbnailImage": "http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_54x108_s.gif", 28 "_highlightResult": { 29 "shortDescription": { 30 "matchLevel": "none", 31 "value": "Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection", 32 "matchedWords": [] 33 }, 34 "category": { 35 "matchLevel": "none", 36 "value": "Computer Security Software", 37 "matchedWords": [] 38 }, 39 "manufacturer": { 40 "matchedWords": [], 41 "value": "Webroot", 42 "matchLevel": "none" 43 }, 44 "name": { 45 "value": "Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows", 46 "matchedWords": [], 47 "matchLevel": "none" 48 } 49 }, 50 "image": "http://img.bbystatic.com/BestBuy_US/images/products/1688/1688832_105x210_sc.jpg", 51 "shipping": "Free shipping", 52 "bestSellingRank": 4, 53 "shortDescription": "Safeguard your PC, Mac, Android and iOS devices with comprehensive Internet protection", 54 "url": "http://www.bestbuy.com/site/webroot-secureanywhere-internet-security-3-devi…d=1219060687969&skuId=1688832&cmp=RMX&ky=2d3GfEmNIzjA0vkzveHdZEBgpPCyMnLTJ", 55 "name": "Webroot SecureAnywhere Internet Security (3-Device) (1-Year Subscription) - Mac/Windows", 56 "category": "Computer Security Software", 57 "salePrice_range": "1 - 50", 58 "objectID": "1688832", 59 "type": "Software", 60 "customerReviewCount": 5980, 61 "salePrice": 49.99, 62 "manufacturer": "Webroot" 63 }, 64 .... 65 ], 66 "nbHits": 10000, 67 "disjunctiveFacets": [ 68 { 69 "exhaustive": false, 70 "data": { 71 "5": 183, 72 "12": 112, 73 "7": 149, 74 ... 75 }, 76 "name": "customerReviewCount", 77 "stats": { 78 "max": 7461, 79 "avg": 157.939, 80 "min": 1 81 } 82 }, 83 { 84 "data": { 85 "Printer Ink": 142, 86 "Wireless Speakers": 60, 87 "Point & Shoot Cameras": 48, 88 ... 89 }, 90 "name": "category", 91 "exhaustive": false 92 }, 93 { 94 "exhaustive": false, 95 "data": { 96 "> 5000": 2, 97 "1 - 50": 6524, 98 "501 - 2000": 566, 99 "201 - 500": 1501, 100 "101 - 200": 1360, 101 "2001 - 5000": 47 102 }, 103 "name": "salePrice_range" 104 }, 105 { 106 "data": { 107 "Dynex™": 202, 108 "Insignia™": 230, 109 "PNY": 72, 110 ... 111 }, 112 "name": "manufacturer", 113 "exhaustive": false 114 } 115 ], 116 "query": "", 117 "nbPages": 100, 118 "page": 0, 119 "index": "bestbuy" 120}
This project works on any ES5 browser, basically >= IE9+.
No vulnerabilities found.