API Reference / API Methods / Upgrade guides for the API client

Upgrade guides for the API client

Upgrading from 3.35.1 to 4.x

We attempt to document every possible breaking change. Since some of these breaking changes happen in obscure parts of the client, only a portion of them may actually affect your application.

The amount of changes in this new version is significant. We strongly recommend that heavily test your application once the migration is over.

To get started, upgrade 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. Additionally, polyfills are required for older browsers that don’t support Promise, Object.entries, and Object.assign.

We recommend loading 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 above 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 directly any of the projects in the list below, you may need to update them to the specified versions. We’ve only tested (and therefore can only guarantee) that the v4 works with these versions.

  • 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>

If you are using angular-instantsearch, please keep using algoliasearch v3, as angular-instantsearch is not yet compatible with algoliasearch v4.

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

We recommend that you directly use the dist/algoliasearch.umd.js build.

The search client

The following sections present the migration guide for the search client itself; that is, the object returned from the algoliasearch function.

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, we recommend you to keep using the v3, or consider using 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

Note that the clearCache method is now async. Therefore, you may need to await on the clearCache method.

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 has been 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.

  • 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, we recommend you to keep using the 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/NodeJS build accepted gzip content from the Algolia API. This feature is not yet available on the v4. If you need it, we recommend you to stay on the v3 for now.

Did you find this page helpful?