Update the JavaScript API client
You should keep your JavaScript API client up to date to benefit from improvements and bug fixes. Algolia’s Service Level Agreement only applies to the latest version of the API client.
The JavaScript API client follows Semantic Versioning. You can check what the latest version of the API client is on the GitHub release page.
Updating from 4.x to latest
Recommendation renamed to Personalization (4.10.2)
To avoid confusion with the newer Algolia Recommend product, the existing “recommendation” client and methods have been renamed to personalization.
@algolia/client-recommendation
→@algolia/client-personalization
initRecommendation()
→initPersonalization()
initRecommendation().getPersonalizationStrategy
→initPersonalization().getPersonalizationStrategy
initRecommendation().setPersonalizationStrategy
→initPersonalization().setPersonalizationStrategy
Updating from 3.35.1 to 4.x
This document lists every known breaking change. Not all these changes may affect your application, since some of these breaking changes happen in obscure parts of the client.
The amount of changes in this new version is significant. You should thoroughly test your application once the migration is over.
To get started, update algoliasearch
to ^4.0.0
.
1
npm install algoliasearch@"^4.0.0"
The client now natively supports TypeScript. If you’re using it in a TypeScript project, you no longer need the @types/algoliasearch
package.
1
npm uninstall @types/algoliasearch
Importing algoliasearch
using ES Modules
Potential impact: very high
Importing the algoliasearch
function via the wildcard (*) is no longer possible. You must import algoliasearch
from the default export.
1
2
3
4
5
6
7
// v3
import * as algoliasearch from 'algoliasearch/lite';
import * as algoliasearch from 'algoliasearch';
// v4
import algoliasearch from 'algoliasearch/lite';
import algoliasearch from 'algoliasearch';
Internet Explorer
Potential impact: very high
If you’re using algoliasearch
in the browser, keep in mind that the version 4 doesn’t support Internet Explorer below version 11.
You also need to use polyfills for older browsers that don’t support Promise
, Object.entries
, and Object.assign
.
You can load these with polyfill.io
:
1
<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CObject.entries%2CObject.assign"></script>
Polyfill.io is a third-party CDN. We are not able to provide support regarding third party services.
Asynchronous methods and callbacks
Potential impact: very high
In the v3, all asynchronous methods took a callback function.
In the v4, you can no longer pass a callback. All asynchronous methods are now exclusively Promise-based:
1
2
3
4
5
6
7
8
9
10
11
// v3
index.search('query string', (err, { hits } = {}) => {
if (err) throw err;
console.log(hits);
});
// v4
index.search('query string').then(({ hits }) => {
console.log(hits);
});
Note: the preceding example applies to all asynchronous methods that used to take a callback.
Compatibility with the Helper and InstantSearch
Potential impact: very high
If you’re using any of the projects in the list below, you may need to update them to the specified versions. All tests on v4 apply to these versions. Other versions may not work.
algoliasearch-helper-js
:>= 2.28.1
algoliasearch-helper-js
:>= 3.1.0
instantsearch.js
:>= 4.2.0
react-instantsearch
:>= 6.3.0
vue-instantsearch
:>= 2.7.0
You also need to add polyfills:
1
2
3
4
5
<!-- v3 -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=default,Array.prototype.find,Array.prototype.includes"></script>
<!-- v4 -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=default%2CArray.prototype.find%2CArray.prototype.includes%2CPromise%2CObject.assign%2CObject.entries"></script>
Angular InstantSearch isn’t yet compatible with algoliasearch
v4. If you’re using Angular InstantSearch, please keep using algoliasearch
v3.
AngularJS, jQuery, and React Native builds
Potential impact: medium
The following builds are no longer available:
dist/algoliasearch.angular.js
dist/algoliasearch.jquery.js
algoliasearch.reactnative.js
You should use the dist/algoliasearch.umd.js
build directly.
The search client
The following sections present the migration guide for the search client itself. The client is the object that the algoliasearch
function returns.
1
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey');
The initPlaces
method
Potential impact: medium
The initPlaces
method is no longer available. If you want to use this feature, either keep using v3 or use the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import algoliasearch from 'algoliasearch/lite';
import { shuffle } from '@algolia/client-common';
const places = (appId = '', apiKey = '', options) => {
const placesClient = algoliasearch(appId, apiKey, {
hosts: [{ url: 'places-dsn.algolia.net' }].concat(
shuffle([
{ url: 'places-1.algolia.net' },
{ url: 'places-2.algolia.net' },
{ url: 'places-3.algolia.net' }
])
),
...options
});
return (query, requestOptions) => {
return placesClient.transporter.read(
{
method: 'POST',
path: '1/places/query',
data: {
query
},
cacheable: true
},
requestOptions
);
};
};
const search = places('', '');
// const search = places('YOUR_PLACES_APP_ID', 'YOUR_PLACES_API_KEY');
search('query string').then(results => {
console.log(results);
});
The timeout
parameter
Potential impact: low
The timeout
parameter is no longer available, here is the alternative:
1
2
3
4
5
6
7
8
9
10
11
12
13
// v3
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
timeout: 2
});
// v4
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
timeouts: {
connect: 1,
read: 2, // The value of the former `timeout` parameter
write: 30
}
});
The protocol
parameter
Potential impact: very low
The parameter is no longer available, here is the alternative:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// v3
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
protocol: 'http'
});
// v4
import { CallEnum } from '@algolia/transporter';
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
hosts: [
{
protocol: 'http', // or 'https'
url: 'domain.com',
accept: CallEnum.Any // CallEnum.Read or CallEnum.Write
}
]
});
The hosts
parameter
Potential impact: very low
The parameter has changed, here is the alternative:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// v3
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
hosts: { read: ['domain.com'] }
});
// v4
import { CallEnum } from '@algolia/transporter';
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
hosts: [
{
protocol: 'https', // or 'http'
url: 'domain.com',
accept: CallEnum.Read // CallEnum.Any or CallEnum.Write
}
]
});
The _useCache
parameter
Potential impact: low
The parameter is no longer available, here is the alternative:
1
2
3
4
5
6
7
8
9
10
11
// v3
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
_useCache: false
});
// v4
import { createNullCache } from '@algolia/cache-common';
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
responsesCache: createNullCache()
});
The clearCache
method
Potential impact: very low
The clearCache
method is now asynchronous. Make sure to adapt your code to wait on the promise resolution if you have dependencies.
1
2
3
4
5
6
7
// v3
client.clearCache();
// v4
client.clearCache().then(() => {
// ...
});
The destroy
method
Potential impact: low
The destroy
method is now asynchronous.
1
2
3
4
5
6
7
// v3
client.destroy();
// v4
client.destroy().then(() => {
// ...
});
The setRequestTimeout
, setTimeouts
, and getTimeouts
methods
Potential impact: low
The setRequestTimeout
, setTimeouts
, and getTimeouts
methods are no longer available. Here is the alternative:
1
2
3
4
5
6
7
8
// v4
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
timeouts: {
connect: 1,
read: 2,
write: 30
}
});
The setExtraHeader
, getExtraHeader
, and unsetExtraHeader
methods
Potential impact: medium
The setExtraHeader
, getExtraHeader
, and unsetExtraHeader
methods are no longer available.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// v3
client.setExtraHeader('key', 'value');
client.getExtraHeader('key');
client.unsetExtraHeader('key');
// v4
// For every request
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
headers: {
key: 'value'
}
});
// For for a single request
index
.search('query', {
headers: {
key: 'value'
}
})
.then(({ hits }) => {
console.log(hits);
});
The setUserToken
method
Potential impact: very low
The method is no longer available, here is the alternative:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// v3
client.setUserToken('userToken');
// v4
const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
headers: {
'x-algolia-usertoken': 'userToken'
}
});
// or
index
.search('query', {
headers: {
'x-algolia-usertoken': 'value'
}
})
.then(({ hits }) => {
console.log(hits);
});
The updateApiKey
method
Potential impact: low
The updateApiKey
method signature has changed.
1
2
3
4
5
6
7
8
// v3
client.updateApiKey('key', ['search']);
// v4
client.updateApiKey('key', {
acl: ['search']
// All remaining key updates below
});
The addUserKeyWithValidity
method
Potential impact: low
The addUserKeyWithValidity
is removed. Please use addApiKey
instead.
The assignUserID
method
Potential impact: low
The assignUserID
method signature has changed.
1
2
3
4
5
6
7
8
// v3
client.assignUserID({
userID: 'myUserID1',
cluster: 'c1-test'
});
// v4
client.assignUserID('myUserID1', 'c1-test');
The assignUserIDs
method
Potential impact: low
The assignUserIDs
method signature has changed.
1
2
3
4
5
6
7
8
// v3
client.assignUserIDs({
userIDs: ['myUserID1', 'myUserID2', 'myUserID3'],
cluster: 'c1-test'
});
// v4
client.assignUserIDs(['myUserID1', 'myUserID2', 'myUserID3'], 'c1-test');
The getUserID
method
Potential impact: low
The getUserID
method signature has changed.
1
2
3
4
5
// v3
client.getUserID({ userID: 'myUserID1' });
// v4
client.getUserID('myUserID1');
The removeUserID
method
Potential impact: low
The removeUserID
method signature has changed.
1
2
3
4
5
// v3
client.removeUserID({ userID: 'myUserID1' });
// v4
client.removeUserID('myUserID1');
The searchUserIDs
method
Potential impact: low
The searchUserIDs
method signature has changed.
1
2
3
4
5
6
7
// v3
client.searchUserIDs({ query: 'query' });
// v4
client.searchUserIDs('query', {
// Any other optional parameter
});
The generateSecuredApiKey
method
Potential impact: low
The generateSecuredApiKey
method signature has changed.
1
2
3
4
5
6
7
// v3
client.generateSecuredApiKey({ apiKey: 'MyApiKey' });
// v4
client.generateSecuredApiKey('MyApiKey', {
// Any other optional parameter
});
The enableRateLimitForward
and disableRateLimitForward
methods
Potential impact: low
Both enableRateLimitForward
and disableRateLimitForward
methods are no longer available. You can now add the X-Forwarded-For
and X-Forwarded-For
headers this way:
1
2
3
4
5
6
algoliasearch('YourApplicationID', 'YourAdminAPIKey', {
headers: {
'X-Forwarded-For': 'userIP',
'X-Forwarded-For': 'rateLimitApiKey'
}
});
Renamed methods
Potential impact: medium
The following methods don’t contain breaking changes, but either their name has changed, or they have been moved.
listIndexes
→listIndices
deleteIndex
→initIndex('indexName').delete()
batch
→multipleBatch
sendQueriesBatch
→search
getTopUserID
→getTopUserIDs
setPersonalizationStrategy
→initRecommendation().setPersonalizationStrategy
getPersonalizationStrategy
→initRecommendation().getPersonalizationStrategy
The search index
The following sections present the migration guide for the search index; that is, the object returned from calling the client.initIndex
method.
1
const index = client.initIndex();
The search
method
Potential impact: very high
The search
method signature has changed.
1
2
3
4
5
6
7
8
9
10
11
// v3
index.search({
query: 'query',
hitsPerPage: 50
});
// v4
index.search('query', {
hitsPerPage: 50
// Any other parameter
});
The searchForFacetValues
method
Potential impact: high
The searchForFacetValues
method signature has changed.
1
2
3
4
5
6
7
8
9
10
11
12
// v3
index.searchForFacetValues({
facetName: 'category',
facetQuery: 'phone',
filters: 'brand:apple'
});
// v4
index.searchForFacetValues('category', 'phone', {
// Any optional param
filters: 'brand:apple'
});
The getObject
, and getObjects
methods
Potential impact: low
Both getObject
and getObjects
are no longer available on the lite
build. Therefore, you need to include the full build to work with those methods. In addition, the signature has changed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// v3
import algoliasearch from 'algoliasearch/lite';
// ...
index.getObject('objectID', ['name']);
index.getObjects(['objectID'], ['name']);
// v4
import algoliasearch from 'algoliasearch';
// ...
index.getObject('objectID', {
attributesToRetrieve: ['name']
});
index.getObjects(['objectID'], {
attributesToRetrieve: ['name']
});
The addObject
and addObjects
methods
Both the addObject
and addObjects
methods no longer exist, and are replaced with the autoGenerateObjectIDIfNotExist
parameter in RequestOptions
on the saveObject
and saveObjects
methods.
Potential impact: medium
1
2
3
4
5
6
7
8
9
10
11
12
// v3
index.addObject({ objectID: '1', name: 'star wars' });
index.addObjects([{ objectID: '1', name: 'star wars' }]);
// v4
index.saveObject(
{ objectID: '1', name: 'star wars' },
{ autoGenerateObjectIDIfNotExist: true }
);
index.saveObjects([{ objectID: '1', name: 'star wars' }], {
autoGenerateObjectIDIfNotExist: true
});
The partialUpdateObject
and partialUpdateObjects
methods
In both partialUpdateObject
and partialUpdateObjects
, the createIfNotExists
parameter should now
be provided in RequestOptions
.
Potential impact: low
1
2
3
4
5
6
7
8
9
10
11
12
// v3
index.partialUpdateObject({ objectID: '1', name: 'star wars' }, true);
index.partialUpdateObjects([{ objectID: '1', name: 'star wars' }], true);
// v4
index.partialUpdateObject(
{ objectID: '1', name: 'star wars' },
{ createIfNotExists: true }
);
index.partialUpdateObjects([{ objectID: '1', name: 'star wars' }], {
createIfNotExists: true
});
The browse
and browseFrom
methods
Potential impact: low
The browseFrom
method has been removed, and the browse
method is no longer available on lite
builds. If you need to use browse
, you need to use the full build. In addition, the signature has changed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// v3
import algoliasearch from 'algoliasearch/lite';
// ...
const browser = index.browseAll();
let hits = [];
browser.on('result', content => {
hits = hits.concat(content.hits);
});
// v4
import algoliasearch from 'algoliasearch';
// ...
let hits = [];
index
.browseObjects({
batch: batch => (hits = hits.concat(batch))
})
.then(() => console.log(hits));
The deleteByQuery
method
Potential impact: low
The method deleteByQuery
has been removed. Please consider using deleteBy
instead.
The ttAdapter
method
Potential impact: very low
The ttAdapter
method is no longer available. If you want to use this feature, please keep using v3.
Renamed methods
Potential impact: medium
The following methods don’t contain breaking changes, but either their name has changed, or they have been moved.
clearIndex
→clearObjects
batchSynonyms
→saveSynonyms
batchRules
→saveRules
listApiKeys
→client.listApiKeys
addApiKey
→client.addApiKey
updateApiKey
→client.updateApiKey
deleteApiKey
→client.deleteApiKey
getApiKey
→client.getApiKey
Others
The usage of gzip
Potential impact: low
The previous version of the CommonJS build accepted gzip content from the Algolia API. This feature isn’t yet available on the v4. If you need it, please stay on v3 for now.