Update the JavaScript API client

This is documentation for v4 of the JavaScript API clients, which is not the latest version. To see the documentation for the latest version, see JavaScript v5.

You should keep your JavaScript API client up to date to benefit from improvements and bug fixes.

The JavaScript API client follows Semantic Versioning.

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().getPersonalizationStrategyinitPersonalization().getPersonalizationStrategy
  • initRecommendation().setPersonalizationStrategyinitPersonalization().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.

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 Algolia search 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 for: Promise, Object.entries, and Object.assign.

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', 'YourWriteAPIKey');

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', 'YourWriteAPIKey', {
  timeout: 2
});

// v4
const client = algoliasearch('YourApplicationID', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  protocol: 'http'
});

// v4
import { CallEnum } from '@algolia/transporter';

const client = algoliasearch('YourApplicationID', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
    hosts: { read: ['domain.com'] }
});

// v4
import { CallEnum } from '@algolia/transporter';

const client = algoliasearch('YourApplicationID', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  _useCache: false
});

// v4
import { createNullCache } from '@algolia/cache-common';

const client = algoliasearch('YourApplicationID', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  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', 'YourWriteAPIKey', {
  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.

  • listIndexeslistIndices
  • deleteIndexinitIndex('indexName').delete()
  • batchmultipleBatch
  • sendQueriesBatchsearch
  • getTopUserIDgetTopUserIDs
  • setPersonalizationStrategyinitRecommendation().setPersonalizationStrategy
  • getPersonalizationStrategyinitRecommendation().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.

  • clearIndexclearObjects
  • batchSynonymssaveSynonyms
  • batchRulessaveRules
  • listApiKeysclient.listApiKeys
  • addApiKeyclient.addApiKey
  • updateApiKeyclient.updateApiKey
  • deleteApiKeyclient.deleteApiKey
  • getApiKeyclient.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.

Did you find this page helpful?
JavaScript API clients v4