@xsolla/metrika
Version:
A lightweight integration library for Xsolla Metrics (XMTS) that simplifies user tracking and analytics setup.
415 lines (327 loc) • 21.3 kB
Markdown
# Xsolla Metrika
[](https://www.npmjs.com/package/@xsolla/metrika)
[](LICENSE)
[](https://bundlephobia.com/result?p=@xsolla/metrika)
[](https://www.npmjs.com/package/@xsolla/metrika)
A lightweight integration library for Xsolla Metrics (XMTS) that simplifies user tracking and analytics setup.
Supports SPA and classic sites, works in all modern browsers (including IE11), and provides full TypeScript support.
---
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [npm / yarn](#npm--yarn)
- [CDN (jsDelivr / unpkg)](#cdn-jsdelivr--unpkg)
- [Usage](#usage)
- [ESM](#esm)
- [CommonJS](#commonjs)
- [IIFE](#iife)
- [IIFE (BOOTSTRAP)](#iife-bootstrap)
- [Configuration](#configuration)
- [Parameters Table](#parameters-table)
- [Sending data](#sending-data)
- [API Reference](#api-reference)
- [Instance Methods](#instance-methods)
- [Trackers](#trackers)
- [What Data Is Sent](#what-data-is-sent)
- [TypeScript Support](#typescript-support)
- [Migration from v1](#migration-from-v1)
- [Browser Support](#browser-support)
- [License](#license)
---
## Features
- 📦 **Tiny**: Minimal bundle size, no heavy dependencies.
- 🧑💻 **TypeScript-first**: Full type definitions out of the box.
- ⚡ **SPA-ready**: Tracks navigation in React, Vue, Angular, etc.
- 🖱️ **Auto-tracking**: Clicks, scrolls, external links, performance, and more.
- 🧬 **Device fingerprinting**.
- 🌍 **Flexible delivery**: Works with `sendBeacon` and `fetch`.
- 🔌 **Custom events**: Send any data, integrate with A/B tests, etc.
---
## Installation
### Bundles
Xsolla Metrika provides several bundle formats for different use cases:
| Format | File | Best For |
| ------ | -------------------------------------- | -------------------------------------------------------------------------- |
| IIFE | `dist/xsolla-metrika.js` | Direct `<script>` inclusion in browsers |
| IIFE | `dist/xsolla-metrika.min.js` | Minified version for browser usage |
| IIFE | `dist/xsolla-metrika.bootstrap.js` | Auto-initialization via `<script data-*>`, available as `window.analytics` |
| IIFE | `dist/xsolla-metrika.bootstrap.min.js` | Minified version of the auto-initialization bundle |
| UMD | `dist/xsolla-metrika.umd.js` | Require.js, Electron, Node.js |
| UMD | `dist/xsolla-metrika.umd.min.js` | Minified UMD version |
| CJS | `dist/xsolla-metrika.cjs.js` | Node.js/CommonJS (`require`) |
| ESM | `dist/xsolla-metrika.esm.js` | Modern bundlers and ESM imports (`import`) |
| Types | `dist/xsolla-metrika.d.ts` | TypeScript type definitions |
### npm / yarn
```bash
npm install @xsolla/metrika
# or
yarn add @xsolla/metrika
```
### CDN (jsDelivr / unpkg)
```html
<!-- jsDelivr (IIFE, 2.4.1) -->
<script src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.4.1"></script>
<!-- unpkg (IIFE, 2.4.1) -->
<script src="https://unpkg.com/@xsolla/metrika@2.4.1"></script>
<!-- For other bundle formats, use: -->
<script src="https://unpkg.com/@xsolla/metrika@2.4.1/dist/xsolla-metrika.umd.js"></script>
```
> **Note:** You can omit the version (`@xsolla/metrika` instead of `@xsolla/metrika@2.4.1`) to always use the latest library version, but this is not recommended for production.
---
## Usage
### ESM
```ts
import XsollaAnalytics from '@xsolla/metrika';
(async () => {
const analytics = await XsollaAnalytics.init({
id: 'YOUR_COUNTER_ID',
hit: true,
navigation: true,
// ...other options
});
analytics.hit(window.location.href);
analytics.elementClick('my-button');
})();
```
### CommonJS
```js
const XsollaAnalytics = require('@xsolla/metrika').default;
XsollaAnalytics.init({ id: 'YOUR_COUNTER_ID', hit: true }).then((analytics) => {
analytics.hit(window.location.href);
});
```
### IIFE
```html
<script src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.4.1"></script>
<script>
window.XsollaAnalytics.init({
id: 'YOUR_COUNTER_ID',
hit: true,
navigation: true,
}).then(function (analytics) {
analytics.hit(window.location.href);
});
</script>
```
### IIFE (BOOTSTRAP)
A special **bootstrap IIFE** bundle: `dist/xsolla-metrika.bootstrap.js` and its minified version `dist/xsolla-metrika.bootstrap.min.js`.
This bundle allows you to specify configuration parameters directly via data-attributes on the `<script>` tag. The analytics instance is then automatically created and becomes available as `window.analytics`.
```html
<script
src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.4.1/dist/xsolla-metrika.bootstrap.min.js"
data-id="123456"
data-hit="true"
data-click="true"
data-ext-link="true"
data-site-domains='["example.com","sub.example.com"]'
></script>
```
> **Note:**
- All parameters must be specified in kebab-case format.
- All values that require parsing (such as arrays or objects) must be enclosed in single quotes.
---
## Configuration
### Parameters Table
| Name | Type | Default | Description |
| -------------------------------------------- | ------------------------------------------- | ---------------------------------- | ----------------------------------------------------- |
| `id` | `string \| number` | **required** | Counter ID (unique for your project) |
| `hit` | `boolean` | `false` | Track page load (pageview) |
| `extLink` | `boolean` | `false` | Track external links (outside `siteDomains`) |
| `click` | `boolean` | `false` | Track clicks on elements with `data-analytics="true"` |
| `scroll` | `boolean` | `false` | Track scroll depth (10%, 50%, 90%) |
| `crossDomainTracking` | `boolean` | `false` | Track transitions to allowed domains (`siteDomains`) |
| `sendLoadMetrics` | `boolean` | `false` | Send performance metrics (LCP, TTFB, etc.) |
| `navigation` | `boolean` | `false` | Track navigation events (SPA support) |
| `siteDomains` | `string[]` | `[location.host]` | List of internal domains for link tracking |
| `server` | `string` | `'https://minimetrika.xsolla.com'` | Analytics server base URL |
| `hitEndpoint` | `string` | `'hit'` | Endpoint for pageview events |
| `externalId` | `number` | `undefined` | External user ID |
| `merchantId` | `number` | `undefined` | Merchant ID |
| `extraValues` | `Record<string, unknown>` | `{}` | Additional custom parameters |
| `abParams` | `Record<string, unknown>` | `{}` | A/B test parameters |
| [`xsollauid`](docs/identifiers.md#xsollauid) | `string` | `auto-generated` | Xsolla user ID |
| `useBeacon` | `boolean` | `true` | Use `sendBeacon` API for sending data |
| `retryOptions` | `{ retries?: number, retryDelay?: number }` | `{ retries: 2, retryDelay: 500 }` | Options for retrying failed fetch requests |
| `ip` | `string` | `undefined` | User IP (for override, optional) |
---
## Sending Data
By default, Xsolla Metrika sends all events using [sendBeacon](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) for maximum reliability (especially during page unload).
- **Global setting:**
If you want to use regular `fetch` instead of `sendBeacon` for manual methods (`hit`, `externalLink`, `elementClick`, etc.), set the `useBeacon: false` parameter during initialization:
```js
XsollaAnalytics.init({
id: 'YOUR_COUNTER_ID',
useBeacon: false,
// ...
});
```
- **Important:**
Automatic trackers (such as auto pageview, click, scroll tracking, etc.) always use `sendBeacon` regardless of the global parameter.
- **Override per event:**
In any manual method (`hit`, `externalLink`, `elementClick`, etc.), you can explicitly specify the sending method using the `useBeacon` option:
```js
analytics.hit(window.location.href, {}, false); // sends via fetch
analytics.hit(window.location.href, {}, true); // sends via sendBeacon
```
- **Retries with fetch:**
If `sendBeacon` is not available or fails, or if you explicitly use `fetch` for sending, the library will automatically retry the request up to **two additional times** (total of 3 attempts) in case of network errors or server errors.
- **Customizing retries:**
You can control the number of retry attempts and delay between them using the `retryOptions` parameter during initialization:
```js
XsollaAnalytics.init({
id: 'YOUR_COUNTER_ID',
retryOptions: {
retries: 5, // Number of retry attempts (default: 2)
retryDelay: 1000, // Delay between retries in ms (default: 500)
},
});
```
If `retryOptions` is not specified, the default is 2 retries with a 500ms delay.
This allows you to flexibly control how events are sent depending on your needs.
---
## API Reference
### Instance Methods
| Method | Arguments | Returns | Description |
| ----------------------- | ---------------------------------------------------------------------------- | --------------------- | ----------------------------------------------- |
| `hit` | `url: string, data?: object, useBeacon?: boolean` | `Promise<boolean>` | Send a pageview event |
| `externalLink` | `url: string, data?: object, useBeacon?: boolean` | `Promise<boolean>` | Track an external link click |
| `elementClick` | `name: string, data?: object, useBeacon?: boolean` | `Promise<boolean>` | Track a named element click |
| `formData` | `name: string, form: object \| FormData, data?: object, useBeacon?: boolean` | `Promise<boolean>` | Track form submission |
| `customEvent` | `name: string, data?: object, useBeacon?: boolean` | `Promise<boolean>` | Send a custom named event |
| `sendCustomData` | `endpoint: string, data: object, useBeacon?: boolean` | `Promise<boolean>` | Send arbitrary data to a custom analytics route |
| `payStationUserSession` | `data: object, useBeacon?: boolean` | `Promise<boolean>` | Track Pay Station user session |
| `eventForLCP` | `useBeacon?: boolean` | `Promise<boolean>` | Send Largest Contentful Paint event |
| `setAbParams` | `abParams: object` | `void` | Update A/B test parameters |
| `setExtraValues` | `extraValues: object` | `void` | Update extra values |
| `getFingerprintHash` | none | `string \| undefined` | Get device fingerprint hash |
| `getFingerprintData` | none | `object \| undefined` | Get raw device fingerprint data |
| `destroy` | none | `void` | Unsubscribe all trackers and clean up resources |
> **Note:** When sending data using any method (`hit`, `externalLink`, `elementClick`, `formData`, `customEvent`, etc.), you can temporarily extend the global `extraValues` or `abParams` by passing them in the data object:
```ts
analytics.hit(window.location.href, {
exv: { extraKey_1: 'extraValue_1', extraKey_2: 'extraValue_2' },
abParams: { abKey_1: 'abValue_1', abKey_2: 'abValue_2' },
});
```
Values passed this way will be added only to the current event and will not modify the global parameters set during initialization.
#### Example
```ts
analytics.hit(window.location.href);
analytics.externalLink('https://external.com');
analytics.elementClick('my-button');
analytics.formData('signup', { email: 'test@example.com' });
analytics.customEvent('my-event', { foo: 1 });
analytics.setAbParams({ experiment: 'A' });
analytics.destroy();
```
---
## List of Event Types
| Type (et) | Symbolic Name | Where Used / How to Enable | Description |
| ------------------------ | ------------------------ | ------------------------------------- | ------------------------------------------------------------ |
| 1 | HIT | PageLoadTracker, NavigationTracker | Page view (pageview), SPA navigation |
| 2 | EXTERNAL_LINK | ExternalLinkTracker, `externalLink()` | Click on an external link (not from `siteDomains`) |
| 3 | ELEMENT_CLICK | ClickTracker, `elementClick()` | Click on element with `data-analytics="true"` or manual call |
| 4 | FORM_DATA | `formData()` | Form submission |
| 5 | CUSTOM_EVENT | `customEvent()` | Custom user event |
| 6 | LCP | PerformanceTracker, `eventForLCP()` | Largest Contentful Paint metric |
| 10 | SCROLL_TOP | ScrollTracker | Scroll to 10% of the page |
| 11 | SCROLL_MIDDLE | ScrollTracker | Scroll to 50% of the page |
| 12 | SCROLL_BOTTOM | ScrollTracker | Scroll to 90% of the page |
| paystation-user-sessions | paystation-user-sessions | `payStationUserSession()` | PayStation user session event |
See [docs/event-types.md](docs/event-types.md) for details.
---
## Trackers
Xsolla Metrika includes several built-in trackers. Enable them via config flags:
| Tracker | Flag | Description |
| ------------------- | --------------------- | --------------------------------------------------- |
| PageLoadTracker | `hit` | Tracks page load (pageview) |
| ClickTracker | `click` | Tracks clicks on `[data-analytics="true"]` elements |
| ExternalLinkTracker | `extLink` | Tracks clicks on external links |
| ScrollTracker | `scroll` | Tracks scroll depth (10%, 50%, 90%) |
| CrossDomainTracker | `crossDomainTracking` | Appends xsollauid to links to allowed domains |
| PerformanceTracker | `sendLoadMetrics` | Tracks web-vitals metrics (LCP) |
| NavigationTracker | `navigation` | Tracks SPA navigation (history API, hashchange) |
See [docs/trackers.md](docs/trackers.md) for details.
---
## What Data Is Sent
Xsolla Metrika collects and sends only technical and anonymized data required for analytics and improving user experience.
**No personal user data is collected or transmitted by default.**
Example of the event data structure
```json
{
"et": 1, // Event type (e.g., HIT, CLICK, etc.)
"library_version": "2.4.1", // Library version
"counter_id": "YOUR_COUNTER_ID", // Your project counter ID
"dfp": "fingerprint_hash", // Device fingerprint
"xsollauid": "user_id", // Xsolla user ID
"eid": 123456, // External ID (if there is)
"ident": {
"ntf": 1, // Notifications enabled (1/0)
"net": "4g", // Network type
"t": "Page Title", // Document title
"pc": "UTF-8", // Charset
"la": "en", // Language
"tz": -180, // Timezone offset (minutes)
"wcw": 1920, // Viewport width
"wch": 1080, // Viewport height
"sw": 1920, // Screen width
"sh": 1080, // Screen height
"j": 0, // Java enabled (1/0)
"c": 1, // Cookies enabled (1/0)
"sc": 24, // Color depth
"ifr": 0, // Is in iframe (1/0)
"adb": 0, // AdBlock detected (1/0)
"gacid": "123456789.1234567890", // Google Analytics CID (if there is)
"clid": "1733820844784899640", // Client ID
"vid": "1747380405323933016", // Visitor ID,
"plt": 356, // Page load time (ms),
"lcp": 567 // Largest Contentful Paint (ms)
// ...additional cookies (for example: yid, pv, cv, etc.)
},
"user_agent": "...", // User-Agent string
"browser_major": "125", // Browser major version
"browser_name": "Chrome", // Browser name
"title": "Page Title", // Document title
"utm": {
"utm_source": null,
"utm_medium": null,
"utm_campaign": null,
"utm_content": null,
"utm_term": null
},
"openstat": {
"openstat_service": null,
"openstat_campaign": null,
"openstat_ad": null,
"openstat_source": null
},
"url": "https://your.site/page", // Current page URL
"referer": "https://referrer.site/", // Referrer URL
"exv": {}, // Extra values (if there is)
"abParams": {} // A/B test params (if there is)
// ...event-specific fields (for example: value, en, form, metricData, etc.)
}
```
---
## TypeScript Support
- 100% typed API, no need for `@types` packages.
- Works out of the box with TypeScript 5.8+.
- See [docs/ts-support.md](docs/ts-support.md) for troubleshooting and tips.
---
## Migration from v1
- Async initialization: use `await XsollaAnalytics.init(...)`.
- Device Fingerprinting has become more reliable.
- Events are sent via `sendBeacon` by default, with fallback to `fetch`.
- The method `dfpGet` has been renamed to `getFingerprintHash`.
- The method `keyDfpGet` has been renamed to `getFingerprintData`.
- Retry logic for failed fetch requests.
- See [docs/migration/v1_v2.md](docs/migration/v1_v2.md) for a full migration guide.
---
## Browser Support
- All modern browsers (Chrome, Firefox, Edge, Safari, Opera, Samsung Internet, etc.)
- IE11+
- See [docs/browser-support.md](docs/browser-support.md) for the full list.
---
## License
[MIT](LICENSE.md) © Xsolla
---