# Migrate from Javascript SDK to Browser SDK 1.0

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

Amplitude Browser SDK 1.0 (`@amplitude/analytics-browser`) features a plugin architecture, built-in type definition and broader support for front-end frameworks. Browser SDK 1.0 isn't backwards compatible with `amplitude-js`.

To migrate to `@amplitude/analytics-browser`, update your dependencies and instrumentation.

> **Note:** Browser SDK 2.0
>
> An improved version of the Amplitude Browser SDK is now available. Amplitude Browser SDK 2.0 features default event tracking, improved marketing attribution tracking, simplified interface and a lighter weight package. Amplitude recommends the Browser SDK 2.0 for both product analytics and marketing analytics use cases. Upgrade to the latest [Browser SDK 2.0](https://amplitude.com/docs/sdks/analytics/browser/browser-sdk-2).

> **Warning:** Breaking changes
>
> Migration to `@amplitude/analytics-browser` may disrupt Web Attribution in your implementation. Before you upgrade, you can choose whether attribution occurs during a session. After you upgrade, attribution always happens during the session, and you can no longer configure this behavior.
>
> In both versions, attribution can happen during initialization.

## Terminology

- `amplitude-js`: Maintenance Browser SDK.
- `@amplitude/analytics-browser`: Browser SDK 1.0.

## Dependency

For snippet installation, update your project's [snippet loader](https://github.com/amplitude/Amplitude-TypeScript/tree/v1.x/packages/analytics-browser#using-script-loader).

For Node projects, update your dependency list in package.json.

#### amplitude-js

```json
{
  "dependencies": {
    "amplitude-js": "^8"
  }
}
```

#### @amplitude/analytics-browser

```json
{
  "dependencies": {
    "@amplitude/analytics-browser": "^1"
  }
}
```

## Instrumentation

Browser SDK 1.0 offers an API to instrument events. To migrate to Browser SDK 1.0, update a few calls. The following sections detail which calls changed.

## Initialization

Like all other calls, Amplitude removed `getInstance()`. To initialize the SDK, call `init()` with the same parameters. The `config` parameter has a different shape. Refer to [Configuration](#configuration).

#### amplitude-js

```javascript
import amplitude from "amplitude-js";

amplitude.getInstance().init(API_KEY, OPTIONAL_USER_ID, config);
```

#### @amplitude/analytics-browser

```typescript
import * as amplitude from "@amplitude/analytics-browser";

amplitude.init(API_KEY, OPTIONAL_USER_ID, config);
```

## Configuration

#### Configuration options

| amplitude-js | @amplitude/analytics-browser |
| --- | --- |
| `config.apiEndpoint` | `config.serverUrl` |
| `config.batchEvents` | `config.flushQueueSize` |
| `config.cookieExpiration` | `config.cookieExpiration` |
| `config.cookieName` | NOT SUPPORTED |
| `config.sameSiteCookie` | `config.cookieSameSite` |
| `config.cookieForceUpgrade` | NOT SUPPORTED |
| `config.deferInitialization` | NOT SUPPORTED. Refer to [Defer initialization](#defer-initialization). |
| `config.disableCookies` | `config.disableCookies` |
| `config.deviceId` | `config.deviceId` |
| `config.deviceIdFromUrlParam` | NOT SUPPORTED |
| `config.domain` | NOT SUPPORTED |
| `config.eventUploadPeriodMillis` | `config.flushIntervalMillis` |
| `config.eventUploadThreshold` | `config.flushQueueSize` |
| `config.forceHTTPs` | NOT SUPPORTED |
| `config.includeFbclid` | NOT SUPPORTED. Refer to [Web attribution](#web-attribution). |
| `config.includeGclid` | NOT SUPPORTED. Refer to [Web attribution](#web-attribution). |
| `config.includeReferrer` | NOT SUPPORTED. Refer to [Web attribution](#web-attribution). |
| `config.includeUtm` | NOT SUPPORTED. Refer to [Web attribution](#web-attribution). |
| `config.language` | NOT SUPPORTED. Refer to [Plugins](#plugins). |
| `config.library` | NOT SUPPORTED. Refer to [Plugins](#plugins). |
| `config.logLevel` | `config.logLevel` |
| `config.logAttributionCapturedEvent` | NOT SUPPORTED |
| `config.optOut` | `config.optOut` |
| `config.onError` | NOT SUPPORTED |
| `config.onExitPage` | NOT SUPPORTED. Refer to [Flush](#flush-or-onexitpage). |
| `config.platform` | NOT SUPPORTED at the configuration level, but `platform` still exists on the event object. To overwrite the platform, assign a platform while tracking an event, or enrich `event.platform` using an enrichment plugin. Refer to [Plugins](#plugins). |
| `config.savedMaxCount` | NOT SUPPORTED |
| `config.saveEvents` | NOT SUPPORTED |
| `config.saveParamsReferrerOncePerSession` | `config.attribution.trackNewCampaigns`. Opposite of `saveParamsReferrerOncePerSession`. Refer to [configuration](#configuration). |
| `config.secureCookie` | `config.cookieSecure` |
| `config.sessionTimeout` | `config.sessionTimeout` |
| `config.storage` | `config.identityStorage` |
| `config.trackingOptions` | `config.trackingOptions` |
| `config.transport` | `config.transportProvider` |
| `config.unsetParamsReferrerOnNewSession` | NOT SUPPORTED. Default behavior. |
| `config.unsentKey` | NOT SUPPORTED |
| `config.unsentIdentifyKey` | NOT SUPPORTED |
| `config.uploadBatchSize` | `config.flushQueueSize` |
| `config.headers` | NOT SUPPORTED |
| `config.serverZone` | `config.serverZone` |
| `config.useDynamicConfig` | NOT SUPPORTED |
| `config.serverZoneBasedApi` | NOT SUPPORTED |
| `config.sessionId` | `config.sessionId` |
| `config.partnerId` | `config.partnerId` |

## Tracking events

The maintenance Browser SDK offered several `logEvent` APIs, such as `logEventWithTimestamp` and `logEventWithGroups`, to override specific properties in the event payload. Amplitude simplified these variations into a unified `track` API in `@amplitude/analytics-browser`.

### logEvent()

The `logEvent()` API maps to `track()`.

#### amplitude-js

```javascript
const eventType = "Button Clicked";
const eventProperties = {
  type: "primary",
};
amplitude.getInstance().logEvent(eventType, eventProperties);
```

#### @amplitude/analytics-browser

```typescript
const eventType = "Button Clicked";
const eventProperties = {
  type: "primary",
};
amplitude.track(eventType, eventProperties);
```

### logEventWithTimestamp()

The `logEventWithTimestamp()` API maps to `track()`.

#### amplitude-js

```javascript
const eventType = "Button Clicked";
const eventProperties = {
  type: "primary",
};
const timestamp = Date.now();
amplitude
  .getInstance()
  .logEventWithTimestamp(eventType, eventProperties, timestamp);
```

#### @amplitude/analytics-browser

```typescript
const eventType = "Button Clicked";
const eventProperties = {
  type: "primary",
};
const eventOptions = {
  time: Date.now(),
};
amplitude.track(eventType, eventProperties, eventOptions);
```

### logEventWithGroups()

The `logEventWithGroups()` API maps to `track()`.

#### amplitude-js

```javascript
const eventType = "Button Clicked";
const eventProperties = {
  type: "primary",
};
const groups = {
  orgId: "12345",
};
amplitude.getInstance().logEventWithGroups(eventType, eventProperties, groups);
```

#### @amplitude/analytics-browser

```typescript
const event_type = "Button Clicked";
const event_properties = {
  type: "primary",
};
const groups = {
  orgId: "12345",
};
const event = {
  event_type,
  event_properties,
  groups,
};
amplitude.track(event);
```

### `sendEvents()`

The `sendEvents()` API maps to `flush()`.

#### amplitude-js

```javascript
amplitude.getInstance().sendEvents();
```

#### @amplitude/analytics-browser

```typescript
amplitude.flush();
```

## Set user properties

The APIs for setting user properties are the same, except `getInstance()` no longer exists. The following code snippets show how to migrate user property APIs.

### setUserId()

> **Warning:** Minimum identifier length
>
> The maintenance SDK uses an old SDK endpoint (`api2.amplitude.com`) which enforces no length limit for `deviceId` and `userId`. The latest SDK uses Amplitude's HTTP V2 API (`api2.amplitude.com/2/httpapi`) and requires identifiers to be at least 5 characters by default. When you migrate to the latest SDK, set `config.minIdLength` to a smaller value if you allowed identifiers with fewer than 5 characters.

Set a `userId` when you invoke `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const userId = "1";
amplitude.getInstance().setUserId(userId);
```

#### @amplitude/analytics-browser

```typescript
const userId = "1";
amplitude.setUserId(userId);
```

### setDeviceId()

> **Warning:** Minimum identifier length
>
> The maintenance SDK uses an old SDK endpoint (`api2.amplitude.com`) which enforces no length limit for `deviceId` and `userId`. The latest SDK uses Amplitude's HTTP V2 API (`api2.amplitude.com/2/httpapi`) and requires identifiers to be at least 5 characters by default. When you migrate to the latest SDK, set `config.minIdLength` to a smaller value if you allowed identifiers with fewer than 5 characters.

Set a `deviceId` when you invoke `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const deviceId = "1";
amplitude.getInstance().setDeviceId(deviceId);
```

#### @amplitude/analytics-browser

```typescript
const deviceId = "1";
amplitude.setDeviceId(deviceId);
```

### setSessionId()

Set a `sessionId` when you invoke `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const sessionId = Date.now();
amplitude.getInstance().setSessionId(sessionId);
```

#### @amplitude/analytics-browser

```typescript
const sessionId = Date.now();
amplitude.setSessionId(sessionId);
```

### clearUserProperties()

Amplitude removed the `clearUserProperties` API. Use the unified `identify` API to remove user properties.

#### amplitude-js

```javascript
amplitude.getInstance().clearUserProperties();
```

#### @amplitude/analytics-browser

```typescript
amplitude.identify(new amplitude.Identify().identify.clearAll());
```

### setUserProperties()

Amplitude removed the `setUserProperties` API. Use the unified `identify` API to add user properties.

#### amplitude-js

```javascript
amplitude.getInstance().setUserProperties({
  membership, "paid",
  payment, "bank",
})
```

#### @amplitude/analytics-browser

```typescript
const identify = new amplitude.Identify();
identify.set("membership", "paid").set("payment", "bank");
amplitude.identify(identify);
```

### identify()

Make an identify call on `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const identify = new amplitude.Identify();
identify.set("membership", "paid");
amplitude.getInstance().identify(identify);
```

#### @amplitude/analytics-browser

```typescript
const identify = new amplitude.Identify();
identify.set("membership", "paid");
amplitude.identify(identify);
```

## Set group properties

### groupIdentify()

Make an identify call on `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const identify = new amplitude.Identify();
identify.set("membership", "paid");
amplitude.getInstance().groupIdentify(identify);
```

#### @amplitude/analytics-browser

```typescript
const identify = new amplitude.Identify();
identify.set("membership", "paid");
amplitude.groupIdentify(identify);
```

## Track revenue

### logRevenueV2()

Track revenue using `revenue()` API on `amplitude` without calling `getInstance()`.

#### amplitude-js

```javascript
const revenue = new amplitude.Revenue();
revenue.setProductId("productId").setPrice(10);
amplitude.getInstance().logRevenueV2(revenue);
```

#### @amplitude/analytics-browser

```typescript
const revenue = new amplitude.Revenue();
revenue.setProductId("productId").setPrice(10);
amplitude.revenue(revenue);
```

## Patterns

### Plugins

The configs `config.language`, `config.library`, and `config.platform` were available in `amplitude-js` to modify event payloads for these specific fields. Although `@amplitude/analytics-browser` doesn't support these configurations, you can add plugins to the new Browser SDK to enrich event payloads.

```ts
import {
  BrowserConfig,
  EnrichmentPlugin,
  Event,
  PluginType,
} from "@amplitude/analytics-types";

export class LibraryModifierPlugin implements EnrichmentPlugin {
  name = "library-modifier";
  type = PluginType.ENRICHMENT as const;

  /**
   * setup() is called on plugin installation
   * example: client.add(new LibraryModifierPlugin());
   */
  setup(config: BrowserConfig): Promise<undefined> {
    this.config = config;
  }

  /**
   * execute() is called on each event instrumented
   * example: client.track('New Event');
   */
  execute(event: Event): Promise<Event> {
    event.library = "my-library-name/1.0.0";
    return Promise.resolve(event);
  }
}
```

To install your custom plugin, use `add()` with your custom plugin as parameter.

```typescript
import { add } from "@amplitude/analytics-browser";

add(new LibraryModifierPlugin());
```

### Defer initialization

To defer initialization in `amplitude-js`, call `init` with `config.deferInitialization` set to `true`, then call `enableTracking()` to formalize initialization and send all enqueued events.

#### amplitude-js

```javascript
amplitude.getInstance().init(API_KEY, OPTIONAL_USER_ID, {
  deferInitialization: true,
});

amplitude.getInstance().logEvent("Event 1");
amplitude.getInstance().logEvent("Event 2");
amplitude.getInstance().logEvent("Event 3");

amplitude.getInstance().enableTracking();
```

#### @amplitude/analytics-browser

Call `init()` after `track()`. The SDK processes all `track()` calls after initialization completes.

```typescript
amplitude.track("Event 1");
amplitude.track("Event 2");
amplitude.track("Event 3");

amplitude.init(API_KEY, OPTIONAL_USER_ID);
```

### Web attribution

In `amplitude-js`, you enable web attribution by enabling the following configurations:

- `config.includeGclid`.
- `config.includeFbclid`.
- `config.includeReferrer`.
- `config.includeUtm`.

In `@amplitude/analytics-browser`, a single configuration controls web attribution: `config.attribution.disabled`. The default value is `false`, which captures all campaign parameters. This configuration collects the same campaign parameters that `amplitude-js` supports.

### Flush or onExitPage

Some scenarios warrant sending events immediately, such as when a user navigates away from a page. This case is common when tracking button clicks that direct the user to another page while sending event payloads in batches.

In `amplitude-js`, use the `onExitPage()` callback.

#### amplitude-js

```javascript
amplitude.getInstance().init(API_KEY, OPTIONAL_USER_ID, {
  onExitPage: () => {
    amplitude.sendEvents();
  },
});
```

#### @amplitude/analytics-browser

Add your own event listener for the `pagehide` event.

```javascript
window.addEventListener("pagehide", () => {
  // Set https transport to use sendBeacon API
  amplitude.setTransport("beacon");
  // Send all pending events to server
  amplitude.flush();
});
```

### Callback

In `amplitude-js`, you pass one `init` callback function to run after initialization, plus two separate callback functions for success and error network requests. Because `@amplitude/analytics-browser` supports Promises (and `async`/`await`), asynchronous methods such as `init()`, `track()`, `identify()`, and `groupIdentify()` return a custom promise interface.

```javascript
const initResult = await amplitude.init("YOUR_API_KEY").promise;
if (initResult.code === 200) {
  // success logic
} else {
  // error logic
}

const result = await amplitude.track("Button Clicked").promise;
if (result.code === 200) {
  // success logic
} else {
  // error logic
}
```
