
The Browser SDK lets you send events to Amplitude.

{% callout type="note" title="Browser SDK 2.0 now available" %}
An improved version of Amplitude Browser SDK is now available. Amplitude [Browser SDK 2.0](/docs/sdks/analytics/browser/browser-sdk-2) features default event tracking, improved marketing attribution tracking, a simplified interface, and a lighter-weight package. Amplitude recommends Browser SDK 2.0 for both product analytics and marketing analytics use cases. Upgrade to the latest Browser SDK 2.0. For more information, refer to the [Migration Guide](/docs/sdks/analytics/browser/migrate-from-browser-sdk-1-0-to-2-0).
{% /callout %}

## Initialize the SDK

{% callout type="note" heading="Sending events" %}
This SDK uses the [HTTP V2](/docs/apis/analytics/http-v2) API and follows the same constraints for events. Make sure all events logged in the SDK include the `event_type` field and at least one of `deviceId` (included by default) or `userId`, and follow the HTTP API's constraints on each field.

To prevent instrumentation issues, device IDs and user IDs must be strings of 5 characters or more. If an event contains a device ID or user ID that's too short, Amplitude removes the ID value from the event. If the event doesn't have a `userId` or `deviceId` value, Amplitude may reject the upload with a 400 status. Override the default minimum length of 5 characters by setting the `minIdLength` config option.
{% /callout %}

Initialize the SDK before you instrument any events. Your Amplitude project's API key is required. You can pass an optional user ID and config object in this call. After initialization, you can use the SDK anywhere in an application.

```ts
// Option 1, initialize with API_KEY only
amplitude.init(API_KEY);

// Option 2, initialize with user ID if it's already known
amplitude.init(API_KEY, "user@amplitude.com");

// Option 3, initialize with configuration
amplitude.init(API_KEY, "user@amplitude.com", options);
```

## Configure the SDK

{% accordion title="Configuration options" %}
| Name | Description | Default Value |
| --- | --- | --- |
|`instanceName`| `string`. The instance name. | `$default_instance` |
|`flushIntervalMillis`| `number`. Sets the interval for uploading events to Amplitude, in milliseconds. | 1,000 (1 second) |
|`flushQueueSize`| `number`. Sets the maximum number of events batched in a single upload attempt. | 30 events |
|`flushMaxRetries`| `number`. Sets the maximum number of retries for failed upload attempts. Applies only to errors that can be retried. | 5 times.|
|`logLevel` | `LogLevel.None` or `LogLevel.Error` or `LogLevel.Warn` or `LogLevel.Verbose` or `LogLevel.Debug`. Sets the log level. | `LogLevel.Warn` |
|`loggerProvider `| `Logger`. Sets a custom `loggerProvider` class from the Logger to emit log messages to your chosen destination. | `Amplitude Logger` |
|`minIdLength`| `number`. Sets the minimum length for the value of `userId` and `deviceId` properties. | `5` |
|`optOut` | `boolean`. Sets permission to track events. A value of `true` prevents Amplitude from tracking and uploading events. | `false` |
|`serverUrl`| `string`. Sets the URL that Amplitude uploads events to. | `https://api2.amplitude.com/2/httpapi` |
|`serverZone`| `EU` or `US`. Sets the Amplitude server zone. Set this to `EU` for Amplitude projects created in the `EU` data center. | `US` |
|`useBatch`| `boolean`. Sets whether to upload events to the Batch API instead of the default HTTP V2 API. | `false` |
|`appVersion` | `string`. Sets an app version for tracked events. This can be the version of your application. For example: "1.0.0". | `undefined` |
|`deviceId` | `string`. Sets an identifier for the device running your application. | `UUID()` |
|`cookieExpiration` | `number`. Sets expiration of cookies created in days. | 365 days |
|`cookieSameSite` | `string`. Sets `SameSite` property of cookies created. | `Lax` |
|`cookieSecure` | `boolean`. Sets `Secure` property of cookies created. | `false` |
|`cookieStorage` | `Storage<UserSession>`. Sets a custom implementation of `Storage<UserSession>` to persist user identity. | `MemoryStorage<UserSession>` |
|`cookieUpgrade`| `boolean`. Sets upgrading from cookies created by the [maintenance Browser SDK](/docs/sdks/analytics/browser/javascript-sdk). If true, the new Browser SDK deletes cookies created by the maintenance Browser SDK. If false, the Browser SDK keeps cookies created by the maintenance Browser SDK. | `true` |
|`disableCookies`| `boolean`. Sets permission to use cookies. If the value is `true`, the SDK uses the localStorage API to persist user identity. | Cookies are enabled by default. |
|`domain` | `string`. Sets the domain property of cookies created. | `undefined` |
|`partnerId` | `string`. Sets partner ID. Amplitude requires the customer who built an event ingestion integration to add the partner identifier to `partner_id`. | `undefined` |
|`sessionTimeout` | `number`. Sets the period of inactivity, in milliseconds, from the last tracked event before a session expires. | 1,800,000 milliseconds (30 minutes) |
|`userId` | `number`. Sets an identifier for the tracked user. Must have a minimum length of 5 characters unless overridden with the `minIdLength` option. | `undefined` |
|`trackingOptions`| `TrackingOptions`. Configures tracking of more properties. For more information, refer to the `Optional tracking` section. | Enable all tracking options by default. |

{% /accordion %}

Along with the basic configuration options, you can configure attribution.

{% accordion title="Attribution options" %}
| Name | Description| Default Value|
|---|----|---|
|`config.attribution.disabled`| `boolean`. Whether to disable attribution tracking. | `false` |
|`config.attribution.excludeReferrers`| `string[]`. Excludes attribution tracking for the provided referrers string. | Includes all referrers by default. |
|`config.attribution.initialEmptyValue`| `string`. Customize the initial empty value for attribution-related user properties to any string value. | `EMPTY` |
|`config.attribution.resetSessionOnNewCampaign`| `boolean`. Whether to reset user sessions when Amplitude detects a new campaign. | `false` |
|`config.attribution.trackNewCampaigns`| `boolean`. Whether to track new campaigns on the current session. | `false` |
|`config.attribution.trackPageViews`| `boolean`. Whether to track page view on attribution. Note that `config.defaultTracking.pageViews` has higher priority than this configuration. For more information, refer to [Advanced configuration for tracking page views](#advanced-configuration-for-tracking-page-views). | `false` |

{% /accordion %}

### Configure batching behavior

To support high-performance environments, the SDK sends events in batches. The `track` method queues every logged event in memory. The SDK flushes events in batches in the background. Customize batch behavior with `flushQueueSize` and `flushIntervalMillis`. By default, the `serverUrl` is `https://api2.amplitude.com/2/httpapi`. To send large batches of data at a time, set `useBatch` to `true` to set `setServerUrl` to the batch event upload API `https://api2.amplitude.com/batch`. Both regular mode and batch mode use the same event upload threshold and flush time intervals.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  // Events queued in memory will flush when number of events exceed upload threshold
  // Default value is 30
  flushQueueSize: 50,
  // Events queue will flush every certain milliseconds based on setting
  // Default value is 10000 milliseconds
  flushIntervalMillis: 20000,
  // Using batch mode with batch API endpoint, `https://api2.amplitude.com/batch`
  useBatch: true,
});
```

### EU data residency

Configure the server zone when you initialize the client to send data to Amplitude's EU servers. The SDK sends data based on the server zone if it's set.

{% callout type="note" title="" %}
For EU data residency, create your project in and use an API key from Amplitude EU.
{% /callout %}

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  serverZone: "EU",
});
```

### Debugging

Control the level of logs the SDK prints to the console with the following `logLevel` settings:

| Log level | Description                                                                                                                                                  |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `none`    | Suppresses all log messages.                                                                                                                                 |
| `error`   | Shows error messages only.                                                                                                                                   |
| `warn`    | Default. Shows error and warning messages.                                                                                                                   |
| `verbose` | Shows informative messages.                                                                                                                                  |
| `debug`   | Shows all messages, including function context information for each public method the SDK invokes. Amplitude recommends this log level for development only. |

Set the `logLevel` parameter.

```ts
amplitude.init(AMPLITUDE_API_KEY, OPTIONAL_USER_ID, {
  logLevel: amplitude.Types.LogLevel.Warn,
});
```

The default logger outputs logs to the developer console. You can provide your own logger implementation based on the `Logger` interface for customization. For example, collecting any error messages from the SDK in a production environment.

Set the logger by configuring the `loggerProvider` with your own implementation.

```ts
amplitude.init(AMPLITUDE_API_KEY, OPTIONAL_USER_ID, {
  loggerProvider: new MyLogger(),
});
```

#### Debug mode

Enable the debug mode by setting the `logLevel` to "Debug", for example:

```ts
amplitude.init(AMPLITUDE_API_KEY, OPTIONAL_USER_ID, {
  logLevel: amplitude.Types.LogLevel.Debug,
});
```

With the default logger, the SDK outputs extra function context information to the developer console when you invoke any SDK public method, including:

- `type`: Category of this context, for example "invoke public method".
- `name`: Name of the invoked function, for example "track".
- `args`: Arguments of the invoked function.
- `stacktrace`: Stacktrace of the invoked function.
- `time`: Start and end timestamp of the function invocation.
- `states`: Useful internal states snapshot before and after the function invocation.

## Track an event

Events represent how users interact with your application. For example, "Button Clicked" might be an action you want to track.

```ts
// Track a basic event
amplitude.track("Button Clicked");

// Track events with optional properties
const eventProperties = {
  buttonColor: "primary",
};
amplitude.track("Button Clicked", eventProperties);
```

You can also pass a `BaseEvent` object to `track`. For all available fields, refer to the [BaseEvent](https://amplitude.github.io/Amplitude-TypeScript/interfaces/_amplitude_analytics_browser.Types.BaseEvent.html) interface.

```ts
const event_properties = {
  buttonColor: "primary",
};

const event = {
  event_type: "Button Clicked",
  event_properties,
  groups: { role: "engineering" },
  group_properties: { groupPropertyKey: "groupPropertyValue" },
};

amplitude.track(event);
```

## Track events to multiple projects

By default, Amplitude SDKs send data to one Amplitude project. To send data to more than one project, add an instance of the Amplitude SDK for each project that should receive data. Then, pass instance variables wherever you call Amplitude. Each instance supports independent `apiKey`, `userId`, `deviceId`, and `settings` values.

```ts
const defaultInstance = amplitude.createInstance();
defaultInstance.init(API_KEY_DEFAULT);

const envInstance = amplitude.createInstance();
envInstance.init(API_KEY_ENV, {
  instanceName: "env",
});
```

## Track default events

Starting in SDK version 1.9.1, the Browser SDK tracks default events, and adds a configuration to control the collection of default events. Browser SDK tracks the following default events:

- Page views.
- Sessions.
- Form interactions.
- File downloads.

- **`config.defaultTracking.pageViews`**
  - **Value**: Optional. `boolean`.
  - **Description**:
    - Enables default page view tracking. If the value is `true`, Amplitude tracks page view events on initialization. Default value is `false`.
    - Tracked event properties include: `[Amplitude] Page Domain`, `[Amplitude] Page Location`, `[Amplitude] Page Path`, `[Amplitude] Page Title`, `[Amplitude] Page URL`.
    - For more information, refer to [Track page views](#track-page-views).
- **`config.defaultTracking.sessions`**
  - **Value**: Optional. `boolean`.
  - **Description**:
    - Enables session tracking. If the value is `true`, Amplitude tracks session start and session end events. Default value is `false`.
    - For more information, refer to [Track sessions](#track-sessions).
- **`config.defaultTracking.formInteractions`**
  - **Value**: Optional. `boolean`.
  - **Description**:
    - Enables form interaction tracking. If the value is `true`, Amplitude tracks form start and form submit events. Default value is `false`.
    - Tracked event properties include: `[Amplitude] Form ID`, `[Amplitude] Form Name`, `[Amplitude] Form Destination`.
    - For more information, refer to [Track form interactions](#track-form-interactions).
- **`config.defaultTracking.fileDownloads`**
  - **Value**: Optional. `boolean`.
  - **Description**:
    - Enables file download tracking. If the value is `true`, Amplitude tracks file download events. Default value is `false`.
    - Tracked event properties include: `[Amplitude] File Extension`, `[Amplitude] File Name`, `[Amplitude] Link ID`, `[Amplitude] Link Text`, `[Amplitude] Link URL`.
    - For more information, refer to [Track file downloads](#track-file-downloads).

Use the following code sample to start tracking all default events. Or, omit the configuration to keep default events disabled.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    pageViews: true,
    sessions: true,
    formInteractions: true,
    fileDownloads: true,
  },
});
```

To track all default events, you can also set `config.defaultTracking` to `true`. This setting enables the SDK to track any new default events that Amplitude may add.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: true,
});
```

### Track page views

When you set `config.defaultTracking.pageViews` to true, Amplitude uses default page view tracking behavior. This setting sends a page view event on initialization, which appears in Amplitude as `[Amplitude] Page Viewed`.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    pageViews: true,
  },
});
```

{% callout type="note" title="Page view event configuration priority" %}
Both `config.defaultTracking.pageViews` and `config.attribution.trackPageViews` configure whether to enable page view tracking, especially when you use the web attribution plugin. The `config.defaultTracking.pageViews` setting has higher priority than `config.attribution.trackPageViews`, which means `config.defaultTracking.pageViews` overrides the attribution page view event setting. When `config.attribution.trackPageViews` is enabled, the SDK tracks page view events only when attribution changes. When `config.defaultTracking.pageViews` is enabled, the SDK tracks page view events when the page changes.
{% /callout %}

#### Advanced configuration for tracking page views

Use advanced configuration for better control of when the SDK sends page view events.

- **`config.defaultTracking.pageViews.trackOn`**
  - **Value**: Optional. `"attribution"` or `() => boolean`.
  - **Description**:
    - Provides advanced control over when the SDK tracks page view events.
    - Omit or set the value to `undefined` to track page view events on initialization.
    - Set the value to `"attribution"` to track page view events only when Amplitude tracks web attribution.
    - Set the value to a function that returns a boolean (`true` or `false`) to track page view events based on your criteria.
- **`config.defaultTracking.pageViews.trackHistoryChanges`**
  - **Value**: Optional. `"pathOnly"` or `"all"`.
  - **Description**:
    - Provides advanced control for single-page applications over when the SDK tracks page views.
    - Omit or set the value to `"all"` to track page view events on any URL navigation change within your single-page application. For example: navigating from `https://amplitude.com/#company` to `https://amplitude.com/#blog`.
    - Set the value to `"pathOnly"` to track page view events on URL path navigation changes only within your single-page application. For example: navigating from `https://amplitude.com/company` to `https://amplitude.com/blog`.
- **`config.defaultTracking.pageViews.eventType`**
  - **Value**: Optional. `string`.
  - **Description**: Customize the `event_type` for the page view event.

For example, you can configure Amplitude to track page views only when the URL path contains a certain substring, for example `home`.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    pageViews: {
      trackOn: () => {
        return window.location.pathname.includes("home");
      },
    },
  },
});
```

Amplitude tracks the following information with page view events.

| Name                                         | Description                                                                                                                                            | Default Value                                 |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------- |
| `event_type`                                 | `string`. The event type for page view event. Configurable through `defaultTracking.pageViews.eventType` or enrichment plugin.                         | `[Amplitude] Page Viewed` from version 1.9.1. |
| `event_properties.[Amplitude] Page Domain`   | `string`. The page domain.                                                                                                                             | location.hostname or ''.                      |
| `event_properties.[Amplitude] Page Location` | `string`. The page location.                                                                                                                           | location.href or ''.                          |
| `event_properties.[Amplitude] Page Path`     | `string`. The page path.                                                                                                                               | location.path or ''.                          |
| `event_properties.[Amplitude] Page Title`    | `string`. The page title.                                                                                                                              | document.title or ''.                         |
| `event_properties.[Amplitude] Page URL`      | `string`. The value of page URL.                                                                                                                       | location.href.split('?')[0] or ''.            |
| `event_properties.${CampaignParam}`          | `string`. The value of `UTMParameters`, `ReferrerParameters`, or `ClickIdParameters`, if any. For possible keys, refer to [Track default events](#track-default-events). | Any undefined `campaignParam` or `undefined`. |

For an example of how to enrich default page view events, such as adding more properties along with page view tracking, refer to [this example](https://github.com/amplitude/Amplitude-TypeScript/blob/main/examples/plugins/page-view-tracking-enrichment/index.ts).

### Track sessions

Set `config.defaultTracking.sessions` to `true` to enable Amplitude to track sessions.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    sessions: true,
  },
});
```

A session is the period of time a user has your website open. For more information, refer to [How Amplitude defines sessions](/docs/data/sources/instrument-track-sessions). When a new session starts, Amplitude tracks a session start event as the first event of the session. The event type for session start is `[Amplitude] Start Session`. When an existing session ends, Amplitude tracks `[Amplitude] End Sessions`, which is the last event of the session.

### Track form interactions

Set `config.defaultTracking.formInteractions` to `true` to enable Amplitude to track form interactions.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    formInteractions: true,
  },
});
```

Amplitude tracks `[Amplitude] Form Started` when the user initially interacts with the form. An initial interaction can be the first change to a text input, radio button, or dropdown.

Amplitude tracks `[Amplitude] Form Submitted` when the user submits the form. If the user submits a form with no initial change to any form fields, Amplitude sends both `[Amplitude] Form Started` and `[Amplitude] Form Submitted` events.

Amplitude can track forms built with `<form>` tags and nested `<input>` tags. For example:

```html
<form id="subscriber-form" name="subscriber-form" action="/subscribe">
  <input type="text" />
  <input type="submit" />
</form>
```

### Track file downloads

Set `config.defaultTracking.fileDownloads` to `true` to enable Amplitude to track file downloads.

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  defaultTracking: {
    fileDownloads: true,
  },
});
```

Amplitude tracks a file download event when a user clicks an anchor or `<a>` tag linked to a file. The event type for file download is `[Amplitude] File Downloaded`. Amplitude determines that the anchor or `<a>` tag links to a file if the file extension matches the following regex:

`pdf|xlsx?|docx?|txt|rtf|csv|exe|key|pp(s|t|tx)|7z|pkg|rar|gz|zip|avi|mov|mp4|mpe?g|wmv|midi?|mp3|wav|wma`

## User properties

User properties are details such as device details, user preferences, or language that help you understand your users at the time they performed an action in your app.

Use Identify to set the user properties of a particular user without sending an event. The SDK supports the operations `set`, `setOnce`, `unset`, `add`, `append`, `prepend`, `preInsert`, `postInsert`, and `remove` on individual user properties. Declare the operations through the provided Identify interface. You can chain multiple operations in a single Identify object. Pass the Identify object to the Amplitude client to send to the server.

{% callout type="note" title="" %}
If you send the Identify call after the event, the results of operations appear immediately in the dashboard user's profile area. However, results don't appear in chart results until you send another event after the Identify call. The Identify call only affects events going forward.

{% /callout %}

### Set a user property

The Identify object provides controls over setting user properties. First, instantiate an Identify object, then call Identify methods on it. Finally, the client can make a call with the Identify object.

```ts
const identifyEvent = new amplitude.Identify();
amplitude.identify(identifyEvent);
```

### Identify.set

This method sets the value of a user property. For example, you can set a role property of a user.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.set("location", "LAX");

amplitude.identify(identifyEvent);
```

### Identify.setOnce

This method sets the value of a user property only one time. The SDK ignores subsequent calls using `setOnce()`. For example, you can set an initial login method for a user. Because only the initial value is tracked, `setOnce()` ignores later calls.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.setOnce("initial-location", "SFO");

identify(identifyEvent);
```

### Identify.add

This method increments a user property by some numerical value. If the user property doesn't have a value set yet, the SDK initializes the property to 0 before incrementing it. For example, you can track a user's travel count.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.add("travel-count", 1);

amplitude.identify(identifyEvent);
```

### Arrays in user properties

You can use arrays as user properties. Directly set arrays or use `prepend`, `append`, `preInsert` and `postInsert` to generate an array.

### Identify.prepend

This method prepends a value or values to a user property array. If the user property doesn't have a value set yet, the SDK initializes the property to an empty list before prepending the new values.

```ts
const identifyEvent = new Identify();
identifyEvent.prepend("visited-locations", "LAX");

identify(identifyEvent);
```

### Identify.append

This method appends a value or values to a user property array. If the user property doesn't have a value set yet, the SDK initializes the property to an empty list before appending the new values.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.append("visited-locations", "SFO");

amplitude.identify(identifyEvent);
```

### Identify.preInsert

This method pre-inserts a value or values to a user property if the value doesn't exist in the user property yet. Pre-insert means inserting the values at the beginning of a given list. If the user property doesn't have a value set yet, the SDK initializes the property to an empty list before pre-inserting the new values. If the user property has an existing value, this method is a no-op.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.preInsert("unique-locations", "LAX");

identify(identifyEvent);
```

### Identify.postInsert

This method post-inserts a value or values to a user property if the value doesn't exist in the user property yet. Post-insert means inserting the values at the end of a given list. If the user property doesn't have a value set yet, the SDK initializes the property to an empty list before post-inserting the new values. If the user property has an existing value, this method is a no-op.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.postInsert("unique-locations", "SFO");

amplitude.identify(identifyEvent);
```

### Identify.remove

This method removes a value or values from a user property if the value exists in the user property. Remove means removing the existing values from the given list. If the user property doesn't have an existing value, this method is a no-op.

```ts
const identifyEvent = new amplitude.Identify();
identifyEvent.remove("unique-locations", "JFK");

amplitude.identify(identifyEvent);
```

## User groups

Amplitude supports assigning users to groups and performing queries, such as Count by Distinct, on those groups. If at least one member of the group has performed the specific event, then the count includes the group.

For example, you want to group your users based on what organization they're in by using an 'orgId'. Joe is in 'orgId' '10', and Sue is in 'orgId' '15'. Sue and Joe both perform a certain event. You can query their organizations in the Event Segmentation Chart.

When setting groups, define a `groupType` and `groupName`. In the previous example, 'orgId' is the `groupType`, and '10' and '15' are the values for `groupName`. Another example of a `groupType` could be 'sport', with `groupName` values like 'tennis' and 'baseball'.

Setting a group also sets the `groupType:groupName` as a user property, and overwrites any existing `groupName` value set for that user's `groupType` and the corresponding user property value. `groupType` is a string, and `groupName` can be either a string or an array of strings to indicate that a user is in multiple groups.

{% callout type="example" title="" %}
If Joe is in 'orgId' '15', then the `groupName` would be '15'.

```ts
// set group with a single group name
amplitude.setGroup("orgId", "15");
```

If Joe is in 'sport' 'soccer' and 'tennis', then the `groupName` would be '["tennis", "soccer"]'.

```ts
// set group with multiple group names
amplitude.setGroup("sport", ["soccer", "tennis"]);
```

{% /callout %}

You can also set event-level groups by passing an `Event` Object with `groups` to `track`. With event-level groups, the group designation applies only to the specific logged event, and doesn't persist on the user unless you explicitly set it with `setGroup`.

```ts
amplitude.track({
  event_type: "event type",
  event_properties: { eventPropertyKey: "event property value" },
  groups: { orgId: "15" },
});
```

## Track revenue

The preferred method of tracking revenue for a user is to use `revenue()` with the provided Revenue interface. Revenue instances store each revenue transaction and let you define several special revenue properties (such as 'revenueType' and 'productIdentifier') that Amplitude's Event Segmentation and Revenue LTV charts use. Pass these Revenue instance objects into `revenue()` to send as revenue events to Amplitude. This method automatically displays revenue-relevant data in the platform. Use this method to track both in-app and non-in-app purchases.

To track revenue from a user, call revenue each time a user generates revenue. In this example, the user purchased three units of a product at $3.99.

```ts
const event = new amplitude.Revenue()
  .setProductId("com.company.productId")
  .setPrice(3.99)
  .setQuantity(3);

amplitude.revenue(event);
```

### Revenue interface

| Name           | Description                                                                                                             | Default Value |
| -------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------- |
| `product_id`   | Optional. `string`. An identifier for the product. Amplitude recommends something like the Google Play Store product ID. | Empty string. |
| `quantity`     | Required. `number`. The quantity of products purchased. Note: revenue = quantity \* price.                              | `1`           |
| `price`        | Required. `number`. The price of the products purchased, and this can be negative. Note: revenue = quantity \* price.   | `null`        |
| `revenue_type` | Optional, but required for revenue verification. `string`. The revenue type (for example, tax, refund, income).         | `null`        |
| `receipt`      | Optional. `string`. The receipt identifier of the revenue.                                                              | `null`        |
| `receipt_sig`  | Optional, but required for revenue verification. `string`. The receipt signature of the revenue.                        | `null`        |
| `properties`   | Optional. `{ [key: string]: any }`. An object of event properties to include in the revenue event.                      | `null`        |

## Flush the event buffer

The `flush` method triggers the client to send buffered events immediately.

```ts
amplitude.flush();
```

By default, the SDK calls `flush` automatically on an interval. To flush the events altogether, control the async flow with the optional Promise interface, for example:

```ts
amplitude.init(API_KEY).promise.then(function () {
  amplitude.track("Button Clicked");
  amplitude.flush();
});
```

## Custom user ID

If your app has its own login system that you want to track users with, you can call `setUserId` at any time.

```ts
amplitude.setUserId("user@amplitude.com");
```

You can also assign the User ID as an argument to the init call.

```ts
amplitude.init(API_KEY, "user@amplitude.com");
```

## Custom session ID

You can assign a new Session ID using `setSessionId`. When setting a custom session ID, make sure the value is in milliseconds since epoch (Unix Timestamp).

```ts
amplitude.setSessionId(Date.now());
```

## Custom device ID

You can assign a new device ID using `deviceId`. When setting a custom device ID, make sure the value is sufficiently unique. Amplitude recommends using a UUID.

```ts
amplitude.setDeviceId(uuid());
```

## Reset when a user logs out

`reset` is a shortcut to anonymize users after they log out, by:

- Setting `userId` to `undefined`.
- Setting `deviceId` to a new UUID value.

With an undefined `userId` and a completely new `deviceId`, the current user appears as a brand new user in the dashboard.

```ts
amplitude.reset();
```

## Opt users out of tracking

You can turn off logging for a given user by setting `setOptOut` to `true`.

```ts
amplitude.setOptOut(true);
```

Amplitude doesn't save or send events to the server while `setOptOut` is enabled, and the setting persists across page loads.

Re-enable logging by setting `setOptOut` to `false`.

```ts
amplitude.setOptOut(false);
```

## Optional tracking

By default, the SDK tracks these properties automatically. You can override this behavior by passing a configuration called `trackingOptions` when initializing the SDK, setting the appropriate options to false.

| Tracking Options     | Default |
| -------------------- | ------- |
| `deviceManufacturer` | `true`  |
| `deviceModel`        | `true`  |
| `ipAddress`          | `true`  |
| `language`           | `true`  |
| `osName`             | `true`  |
| `osVersion`          | `true`  |
| `platform`           | `true`  |

```ts
amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  trackingOptions: {
    deviceManufacturer: false,
    deviceModel: false,
    ipAddress: false,
    language: false,
    osName: false,
    osVersion: false,
    platform: false,
  },
});
```

## Callback

You can optionally await all asynchronous APIs through a Promise interface. The Promise interface also serves as a callback interface.

{% code-group %}
```ts Promise
amplitude.init("apikey", "12321.com").promise.then(function () {
  // init callback
});

amplitude.track("Button Clicked").promise.then(function (result) {
  result.event; // {...} (The final event object sent to Amplitude)
  result.code; // 200 (The HTTP response status code of the request.
  result.message; // "Event tracked successfully" (The response message)
});
```

```ts async/await
// Using async/await
const initResult = await amplitude.init("apikey", "12321.com").promise;

const results = await amplitude.track("Button Clicked").promise;
result.event; // {...} (The final event object sent to Amplitude)
result.code; // 200 (The HTTP response status code of the request.
result.message; // "Event tracked successfully" (The response message)
```
{% /code-group %}

## Plugins

Plugins let you extend the Amplitude SDK's behavior by, for example, modifying event properties (enrichment type) or sending to third-party APIs (destination type). A plugin is an object with methods `setup()` and `execute()`.

### `add`

The `add` method adds a plugin to Amplitude. Plugins can help process and send events.

```ts
amplitude.add(new Plugin());
```

### `remove`

The `remove` method removes the given plugin name from the client instance if it exists.

```ts
amplitude.remove(plugin.name);
```

### Create your custom plugin

#### Plugin.setup

This method contains logic for preparing the plugin for use and takes config as a parameter. The expected return value is undefined. A typical use for this method is to copy configuration from config or instantiate plugin dependencies. The SDK calls this method when you register the plugin to the client through `amplitude.add()`.

#### Plugin.execute

This method contains the logic for processing events and takes event as a parameter. If used as an enrichment type plugin, the expected return value is the modified or enriched event. If used as a destination type plugin, the expected return value is a map with keys: `event` (BaseEvent), `code` (number), and `message` (string). The SDK calls this method for each event instrumented through the client interface, including Identify, GroupIdentify, and Revenue events.

### Plugin examples

#### Destination type plugin

Here's an example of a plugin that sends each instrumented event to a target server URL using your preferred HTTP client.

```ts
function myDestinationPlugin (serverUrl) {
  const name = 'my-destination-plugin';
  const type = amplitude.Types.PluginType.DESTINATION;
  let amplitudeConfig;

  /**
   * setup() is called on plugin installation
   * example: amplitude.add(new myDestinationPlugin());
   */
  const setup = function (config) {
    amplitudeConfig = config;
  }

  /**
   * execute() is called on each event instrumented
   * example: amplitude.track('New Event');
   */
  const execute = function (event) {
    const payload = {
      key: 'secret',
      data: event,
    };
    return fetch(this.serverUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: '*/*',
      },
      body: JSON.stringify(payload),
    }).then(function(response) {
      return {
        code: response.status,
        event: event,
        message: response.statusText,
      };
    });
  }

  return {
    name,
    type,
    setup,
    execute,
  },
}

amplitude.init(API_KEY);
amplitude.add(myDestinationPlugin('https://custom.domain.com'));
```

#### Enrichment type plugin

Here's an example of a plugin that modifies each instrumented event by adding an increment integer to the `event_id` property of an event, starting from 100.

```ts
const addEventIdPlugin = () => {
  const name = "add-event-id";
  const type = amplitude.Types.PluginType.ENRICHMENT;
  let currentId = 100;
  let amplitudeConfig;

  /**
   * setup() is called on plugin installation
   * example: amplitude.add(new AddEventIdPlugin());
   */
  const setup = function (config) {
    amplitudeConfig = config;
  };

  /**
   * execute() is called on each event instrumented
   * example: client.track('New Event');
   */
  const execute = function (event: Event) {
    event.event_id = currentId++;
    return event;
  };

  return {
    name,
    type,
    setup,
    execute,
  };
};

amplitude.init(API_KEY);
amplitude.add(addEventIdPlugin());
```

#### Web attribution enrichment plugin

Download the `plugin-web-attribution-browser` package and add the `webAttributionPlugin` before you call the `init` method.

{% code-group %}
```bash npm
npm install @amplitude/plugin-web-attribution-browser
```

```bash yarn
yarn add @amplitude/plugin-web-attribution-browser
```
{% /code-group %}

Add the plugin to the Amplitude instance.

```ts
amplitude.add(webAttributionPlugin());
amplitude.init(API_KEY);
```

For configuration details, refer to the [configuration options](/docs/sdks/analytics/browser/marketing-analytics-sdk#configuration).

For details on what the [Web Attribution Plugin](/docs/sdks/analytics/browser/marketing-analytics-sdk#marketing-attribution) supports, refer to the plugin documentation.

##### Differences from the base SDK

Enabling the Attribution plugin overrides the default attribution tracking behavior of the SDK.

The SDK's built-in attribution tracking only tracks attribution at the start of sessions. This means if a user re-enters the site through a new campaign channel (such as direct or an ad) in the middle of a session, the SDK doesn't record this new channel.

If the `trackNewCampaigns` option is set to `true`, the SDK tracks the campaigns and resets the user's session when it detects a new campaign.

The Attribution plugin tracks all campaigns, regardless of whether the user is at the start of a session.

Set the `resetSessionOnNewCampaign` option to `true` to reset the user's session when Amplitude detects a new campaign. The session doesn't reset when the referrer is a different subdomain of your site.

#### Page view enrichment plugin

Download the `plugin-page-view-tracking-browser` and add `pageViewTrackingPlugin` before calling the init method.

{% code-group %}
```bash npm
npm install @amplitude/plugin-page-view-tracking-browser
```

```bash yarn
yarn add @amplitude/plugin-page-view-tracking-browser
```
{% /code-group %}

Add plugin to the Amplitude instance.

```ts
amplitude.add(pageViewTrackingPlugin());
amplitude.init(API_KEY);
```

For configuration details, refer to the [configuration options](/docs/sdks/analytics/browser/marketing-analytics-sdk#configuration).
For details on what the [Page View Plugin](/docs/sdks/analytics/browser/marketing-analytics-sdk#page-view) supports, refer to the plugin documentation.

##### Differences from base SDK

The base SDK sends Page View events when Amplitude tracks a user's campaign, if the `attribution.trackPageViews` option is set to `true`.

The page view plugin sends a Page View event on each page a user visits by default. The plugin also offers options to customize this behavior.

## Troubleshooting and debugging

Debugging in a browser can help you identify problems related to your code's implementation, as well as potential issues within the SDKs you use. Here's a basic guide on how to use the browser's built-in Developer Tools (DevTools) for debugging.

### Console

You can find JavaScript errors under *Inspect > Console*, which might have the details about the line of code and file that caused the problem. The console also lets you execute JavaScript code in real time.

- Enable debug mode by following the [debug mode instructions](#debug-mode). Then with the default logger, the SDK outputs extra function context information to the developer console when you invoke any SDK public method, which can be helpful for debugging.

- Amplitude supports SDK deferred initialization. Amplitude dispatches events tracked before initialization after the initialization call. If you can't send events but can send the event successfully after entering `amplitude.init(API_KEY, 'USER_ID')` in the browser console, your `amplitude.init` call might not have been triggered in your codebase, or you aren't using the correct Amplitude instance during initialization.

### Network request

Use the *Inspect > Network* tab to view all network requests made by your page. Search for the Amplitude request.

Check the response code and ensure the response payload is as expected.

### Instrumentation Explorer/Chrome extension

The Amplitude Instrumentation Explorer is an extension available in the Google Chrome Web Store. The extension captures each Amplitude event you trigger and displays it in the extension popup. Ensure that Amplitude sent the event successfully and check the context in the event payload.

For more details, refer to the [event stream analysis guide](/docs/analytics/debug-analytics#step-2-analyze-the-event-stream).

## Common issues

The following are common issues specific to Browser SDK. For more general common issues, refer to [SDK Troubleshooting and Debugging](/docs/sdks/sdk-debugging).

### Ad Blocker

`Ad Blocker` might cause event dropping. These errors show that `Ad Blocker` has affected tracking. When loading through a script tag, an error may appear in the console or network tab while loading the SDK script. When loaded with the npm package, errors might appear in the network tab when the SDK tries to send events to the server. The errors might vary depending on the browser.

- Chrome (Ubuntu, MacOS)
  Console: error net::ERR_BLOCKED_BY_CLIENT
  Network: status (blocked:other)
- Firefox (Ubuntu)
  Console: error text doesn't contain any blocking-specific info
  Network: Transferred column contains the name of plugin Blocked by uBlock Origin
- Safari (MacOS)
  Console: error contains text Content Blocker prevented frame ... from loading a resource from ...
  Network: blocked requests aren't listed. It's unclear whether the browser can show them.

Amplitude recommends using a proxy server to avoid this situation.

### Cookies related

For details on the [information](#cookie-management) the SDK stores in cookies, refer to the cookie management section. Client behavior, such as disabling cookies or using a private browser, window, or tab, affects the persistence of these saved values in the cookies. If these values aren't persistent or aren't increasing by one, that could be the reason.

### CORS

Cross-Origin Resource Sharing (CORS) is a security measure browsers implement to restrict how resources on a web page can be requested from a different domain. CORS might cause this issue if you used `setServerURL`.

`Access to fetch at 'xxx' from origin 'xxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.`

Cross-origin resource sharing (CORS) prevents a malicious site from reading another site's data without permission. The error message suggests that the server you're trying to access isn't allowing your origin to access the requested resource. This is due to the lack of the `Access-Control-Allow-Origin` header in the server's response.

- If you have control over the server, you can update the server's CORS policy. Add the `Access-Control-Allow-Origin` header to the server's responses. This would allow your origin to make requests. The value of `Access-Control-Allow-Origin` can be \* to allow all origins, or it can be the specific URL of your web page.

- If you don't have control over the server, you can set up a proxy server that adds the necessary CORS headers. The web page makes requests to the proxy, which then makes requests to the actual server. The proxy adds the `Access-Control-Allow-Origin` header to the response before sending it back to the web page.

If you've set up an API proxy and run into configuration issues related to that on a platform you've selected, that's no longer an SDK issue but an integration issue between your application and the service provider.

### Events fired but no network requests

If you [set the logger to "Debug" level](#debug-mode) and see track calls in the developer console, the SDK has called the `track()` method. If you don't see the corresponding event in Amplitude, the Amplitude Instrumentation Explorer Chrome extension, or the network request tab of the browser, Amplitude didn't receive the event. The SDK sends events and places them in the SDK's internal queue upon a successful `track()` call, but sometimes these queued events may not send successfully. This can happen when an in-progress HTTP request is cancelled. For example, if you close the browser or leave the page.

There are two ways to address this issue:

1. If you use standard network requests, set the transport to `beacon` during initialization, or set the transport to `beacon` on page exit. `sendBeacon` doesn't work in this case because it sends events in the background and doesn't return server responses like `4xx` or `5xx`. As a result, it doesn't retry on failure. `sendBeacon` only sends scheduled requests in the background. For more information, refer to the [sendBeacon section](#use-sendbeacon).

2. To make track() synchronous, [add the `await` keyword](#callback) before the call.

## Advanced topics

### Cross-domain tracking

You can track anonymous behavior across two different domains. Amplitude identifies anonymous users by their device IDs, which must be passed between the domains. For example:

- Site 1: `www.example.com`.
- Site 2: `www.example.org`.

For users who start on Site 1 and then navigate to Site 2, you must pass the device ID generated from Site 1 as a parameter to Site 2. Site 2 then needs to initialize the SDK with the device ID.

The SDK can parse the URL parameter automatically if `deviceId` is in the URL query parameters.

1. From Site 1, get the device ID from `getDeviceId()`.
2. Pass the device ID to Site 2 through a URL parameter when the user navigates. For example: `www.example.com?deviceId=device_id_from_site_1`.
3. Initialize the Amplitude SDK on Site 2 with `init('API_KEY', null)`.

If you don't provide the `deviceId` with `init`, like `init('API_KEY', null, { deviceId: 'custom-device-id' })`, the SDK automatically falls back to using the URL parameter.

### Custom HTTP client

You can provide an implementation of the `Transport` interface to the `transportProvider` configuration option for customization. For example, sending requests to your proxy server with customized HTTP request headers.

```ts
class MyTransport {
  send(serverUrl, payload) {
    // check example: https://github.com/amplitude/Amplitude-TypeScript/blob/main/packages/analytics-client-common/src/transports/fetch.ts
  }
}

amplitude.init(API_KEY, OPTIONAL_USER_ID, {
  transportProvider: new MyTransport(),
});
```

### Use sendBeacon

Unlike standard network requests, sendBeacon sends events in the background, even if the user closes the browser or leaves the page.

{% callout type="warning" heading="" %}
`sendBeacon` sends events in the background, which means events dispatched from `sendBeacon` don't return a server response and the SDK can't retry them when they encounter failures like 4xx or 5xx errors. You can address these retry issues by sending one event per request, but this could increase the network load and the likelihood of throttling.
{% /callout %}

#### Set the transport to use sendBeacon for all events

To send an event using `sendBeacon`, set the transport SDK option to 'beacon' in one of two ways:

```ts
amplitude.init(API_KEY, "user@amplitude.com", {
  transport: TransportType.SendBeacon,
  // To make sure the event will be scheduled right away.
  flushIntervalMillis: 0,
  flushQueueSize: 1,
});
```

#### Set the transport to use beacon only when exiting page

Amplitude recommends adding your own event listener for `pagehide` event.

```ts
window.addEventListener("pagehide", () => {
  amplitude.setTransport("beacon");
  // Sets https transport to use `sendBeacon` API
  amplitude.flush();
});
```

### Content security policy (CSP)

If your web app configures the strict Content Security Policy (CSP) for security concerns, adjust the policy to allow the Amplitude domains:

- When using the [Script Loader](https://github.com/amplitude/Amplitude-TypeScript/tree/main/packages/analytics-browser#installing-via-script-loader), add `https://*.amplitude.com` to `script-src`.
- Add `https://*.amplitude.com` to `connect-src`.

### Cookie management

The Browser SDK uses cookie storage to persist information that multiple subdomains of the same domain may want to share. This information includes user sessions and marketing campaigns, which the SDK stores in separate cookie entries.

#### Cookie prefix

- `AMP`: The SDK creates user session cookies with `AMP` prefix and the first ten digits of the API key: `AMP_{first_ten_digits_API_KEY}`.
- `AMP_MKTG`: The SDK creates marketing campaign cookies with `AMP_MKTG` and the first ten digits of the API key: `AMP_MKTG_{first_ten_digits_API_KEY}`.
- `AMP_TEST`: On initialization, the SDK creates a cookie with `AMP_TEST` prefix to check whether cookie storage is working properly. The SDK sets the value as the current time, retrieves the cookie by a key, and checks if the retrieved value matches the original set time. You can safely delete the `AMP_TEST` prefix cookies if they aren't successfully deleted for some reason.
- `AMP_TLDTEST`: On initialization, the SDK creates a cookie with `AMP_TLDTEST` prefix to find a subdomain that supports cookie storage. For example, when checking for cookie support on `https://analytics.amplitude.com/amplitude/home`, the SDK first tries to find a subdomain that matches the root domain (`amplitude.com`) and then falls back to the full domain (`analytics.amplitude.com`). You can safely delete the `AMP_TLDTEST` prefix cookies if they aren't successfully deleted for some reason.

#### Cookie domain

By default, the SDK assigns these cookies to the top-level domain that supports cookie storage. Cookies can be shared on multiple subdomains, which provides a consistent user experience across all subdomains.

For example, a user logs into the website on one subdomain (`data.amplitude.com`) where the SDK is initialized. On initialization, the SDK assigns cookies to `.amplitude.com`. If the user then navigates to another subdomain (`analytics.amplitude.com`), shared cookies share the login information.

#### Cookie data

The SDK creates two types of cookies: user session cookies and marketing campaign cookies.

{% accordion title="User session cookies" %}
|Name| Description|
|---|----|
|`optOut`|Required. A flag to opt this device out of Amplitude tracking. If this flag is set, the SDK doesn't store extra information for the user.|
|`userId`|Upon user log-in, if you send this value, the SDK stores it in the cookie. Set this to uniquely identify users (non-anonymous navigation). The SDK stores it encoded using Base64.|
|`deviceId`|A randomly generated string. The device ID persists unless a user clears their browser cookies or browses in private mode. Even if a user consistently uses the same device and browser, the device ID can still vary.|
|`sessionId`|A randomly generated string for each session.|
|`lastEventTime`|Time of the last event. Used to decide when to expire and create a new session ID.|
|`lastEventId`|ID of the last event.|

{% /accordion %}

{% accordion title="Marketing campaign cookies" %}
|Name| Description|
| --- | --- |
|`utm_campaign`| Identifies a specific campaign used (for example, "summer_sale"). |
|`utm_content` | Identifies what brought the user to the site, commonly used for A/B testing (for example, "banner-link", "text-link"). |
|`utm_id`|An optional parameter for tracking unique IDs or transaction IDs associated with the link.|
|`utm_medium`| Identifies a specific campaign used (for example, "summer_sale"). |
|`utm_source`| Identifies which website sent the traffic (for example, Google, Facebook). |
|`utm_term`| Identifies paid search terms used (for example, product+analytics). |
|`referrer`|The last page the user was on (for example, `https://amplitude.com/behavioral-analytics-platform?ref=nav`).|
|`referring_domain`|The domain that the user was last on (for example, `https://amplitude.com`).|
|`dclid`|Google campaign manager Click Identifier.|
|`gbraid`|Google Click Identifier for iOS device from Web to App.|
|`gclid`|Google Click Identifier from URL parameters.|
|`fbclid`|Facebook Click Identifier from URL parameters.|
|`ko_click_id`|Kochava Click Identifier from URL parameters.|
|`msclkid`|Microsoft Click Identifier.|
|`ttclid`|TikTok Click Identifier.|
|`twclid`|Twitter Click Identifier from URL parameter.|
|`wbraid`|Google Click Identifier for iOS device from App to Web.|
|`li_fat_id`|LinkedIn member indirect identifier for Members for conversion tracking, retargeting, analytics.|
|`rdt_cid`|Reddit Click Identifier.|

{% /accordion %}

#### Disable cookies

You can opt-out of using cookies by setting `disableCookies` to `true` so that the SDK uses `LocalStorage` instead. `LocalStorage` is a useful alternative, but because access to `LocalStorage` is restricted by subdomain, you can't track anonymous users across subdomains of your product (for example: `www.amplitude.com` vs `analytics.amplitude.com`).

### Device ID lifecycle

The SDK initializes the device ID in the following order, setting the device ID to the first valid value encountered:

1. Device ID in configuration on initialization.
2. `deviceId` value from URL parameter, for example `http://example.com/?deviceId=123456789`. For more details, refer to [cross domain tracking](#cross-domain-tracking).
3. Device ID in cookie storage. For more details, refer to [cookie management](#cookie-management).
4. Device ID in cookie storage of Browser SDK. For more details, refer to [cookie management](/docs/sdks/analytics/browser/browser-sdk-2#cookie-management).
5. A randomly generated 36-character UUID.

#### When does a device ID change

A device ID changes in many scenarios:

{% callout type="note" heading="Amplitude Analytics SDKs share an identity store with Experiment SDKS" %}
`setDeviceId` also updates the identity store to propagate new user info to experiment SDK and trigger a fetch if device ID has changed.
{% /callout %}

- You explicitly call `setDeviceId()`.
- By default, the SDK stores device IDs in cookies, so a device ID changes if a user clears cookies, uses another device, or uses privacy mode.
- On initialization, the URL parameter `deviceId` passes in a device ID.
- You call `reset()`.

#### Custom device ID

You can assign a new device ID using `setDeviceId()`. When setting a custom device ID, make sure the value is sufficiently unique. Amplitude recommends using a UUID.

```ts
amplitude.setDeviceId(uuid());
```

#### Get device ID

You can use the helper method `getDeviceId()` to get the value of the current `deviceId`.

```ts
const deviceId = amplitude.getDeviceId();
```
