> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upgrade the JavaScript API client to version 4

> Keep your JavaScript API client up to date to benefit from improvements and bug fixes.

export const Legacy = ({title, href}) => {
  return <Note>

    This page documents an earlier version of the API client.
    For the latest version, see <a href={href}>{title}</a>.

    </Note>;
};

<Legacy title="Upgrade" href="/doc/libraries/sdk/upgrade/javascript" />

The JavaScript API client follows [semantic versioning](http://semver.org).

## Upgrade from version 4.x to the latest version 4

### Recommendation renamed to Personalization (4.10.2)

To avoid confusion with the 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`

## Upgrade from version 3 to version 4

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.

<Check>
  The amount of changes in this new version is significant.
  **You should thoroughly test your application once the migration is over.**
</Check>

To get started, update `algoliasearch` to `^4.0.0`.

```sh Command line icon=square-terminal theme={"system"}
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.

```sh Command line icon=square-terminal theme={"system"}
npm uninstall @types/algoliasearch
```

## Import `algoliasearch` using ES modules

**Potential impact:** high
Importing the `algoliasearch` function with the wildcard (`*`) is no longer possible.
You must import `algoliasearch` from the default export.

```js JavaScript icon=code theme={"system"}
// 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:** 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:** 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:

```js JavaScript icon=code theme={"system"}
// v3
index.search("query string", (err, { hits } = {}) => {
  if (err) throw err;

  console.log(hits);
});

// v4
index.search("query string").then(({ hits }) => {
  console.log(hits);
});
```

<Info>The preceding example applies to all asynchronous methods that used to take a callback.</Info>

## Compatibility with the Algolia search helper and InstantSearch

**Potential impact:** 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 version 4 apply to these versions.**
Other versions may not work.

* [`algoliasearch-helper-js`](/doc/guides/building-search-ui/upgrade-guides/js#algolia-search-helper): `>= 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 compatible with `algoliasearch` version 4.
If you're using Angular InstantSearch, keep using `algoliasearch` version 3.

## 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`

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.

```js JavaScript icon=code theme={"system"}
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY");
```

### The `timeout` parameter

**Potential impact:** low

The `timeout` parameter is no longer available, here is the alternative:

```js JavaScript icon=code theme={"system"}
// v3
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  timeout: 2,
});

// v4
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  timeouts: {
    connect: 1,
    read: 2, // The value of the former `timeout` parameter
    write: 30,
  },
});
```

### The `protocol` parameter

**Potential impact:** low
The parameter is no longer available, here is the alternative:

```js JavaScript icon=code theme={"system"}
// v3
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  protocol: "http",
});

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

const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  hosts: [
    {
      protocol: "http", // or 'https'
      url: "domain.com",
      accept: CallEnum.Any, // CallEnum.Read or CallEnum.Write
    },
  ],
});
```

### The `hosts` parameter

**Potential impact:** low
The parameter has changed, here is the alternative:

```js JavaScript icon=code theme={"system"}
// v3
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  hosts: { read: ["domain.com"] },
});

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

const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  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:

```js JavaScript icon=code theme={"system"}
// v3
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  _useCache: false,
});

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

const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  responsesCache: createNullCache(),
});
```

### The `clearCache` method

**Potential impact:** low
The `clearCache` method is now asynchronous.
Make sure to adapt your code to wait on the promise resolution if you have dependencies.

```js JavaScript icon=code theme={"system"}
// v3
client.clearCache();

// v4
client.clearCache().then(() => {
  // ...
});
```

### The `destroy` method

**Potential impact:** low

The `destroy` method is now asynchronous.

```js JavaScript icon=code theme={"system"}
// 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:

```js JavaScript icon=code theme={"system"}
// v4
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  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.

```js JavaScript icon=code theme={"system"}
// v3
client.setExtraHeader("key", "value");
client.getExtraHeader("key");
client.unsetExtraHeader("key");

// v4

// For every request
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  headers: {
    key: "value",
  },
});

// For for a single request
index
  .search("query", {
    headers: {
      key: "value",
    },
  })
  .then(({ hits }) => {
    console.log(hits);
  });
```

### The `setUserToken` method

**Potential impact:** low
The method is no longer available, here is the alternative:

```js JavaScript icon=code theme={"system"}
// v3
client.setUserToken("userToken");

// v4
const client = algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  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.

```js JavaScript icon=code theme={"system"}
// 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. Use `addApiKey` instead.

### The `assignUserID` method

**Potential impact:** low

The `assignUserID` method signature has changed.

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// v3
client.getUserID({ userID: "myUserID1" });

// v4
client.getUserID("myUserID1");
```

### The `removeUserID` method

**Potential impact:** low

The `removeUserID` method signature has changed.

```js JavaScript icon=code theme={"system"}
// v3
client.removeUserID({ userID: "myUserID1" });

// v4
client.removeUserID("myUserID1");
```

### The `searchUserIDs` method

**Potential impact:** low

The `searchUserIDs` method signature has changed.

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// 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:

```js JavaScript icon=code theme={"system"}
algoliasearch("ALGOLIA_APPLICATION_ID", "ALGOLIA_API_KEY", {
  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,
which is the object returned by the `client.initIndex` method.

```js JavaScript icon=code theme={"system"}
const index = client.initIndex();
```

### The `search` method

**Potential impact:** high
The `search` method signature has changed.

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// 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

```js JavaScript icon=code theme={"system"}
// 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

```js JavaScript icon=code theme={"system"}
// 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.

```js JavaScript icon=code theme={"system"}
// 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. Consider using `deleteBy` instead.

### The `ttAdapter` method

**Potential impact:** low
The `ttAdapter` method is no longer available. If you want to use this feature, 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`

## 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 available on version 4.**
