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
- Installation
- Usage
- Configuration
- Sending data
- API Reference
- Trackers
- What Data Is Sent
- TypeScript Support
- Migration from v1
- Browser Support
- 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
andfetch
. - 🔌 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
npm install @xsolla/metrika
# or
yarn add @xsolla/metrika
CDN (jsDelivr / unpkg)
<!-- jsDelivr (IIFE, 2.2.3) -->
<script src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.2.3"></script>
<!-- unpkg (IIFE, 2.2.3) -->
<script src="https://unpkg.com/@xsolla/metrika@2.2.3"></script>
<!-- For other bundle formats, use: -->
<script src="https://unpkg.com/@xsolla/metrika@2.2.3/dist/xsolla-metrika.umd.js"></script>
Note: You can omit the version (
@xsolla/metrika
instead of@xsolla/metrika@2.2.3
) to always use the latest library version, but this is not recommended for production.
Usage
ESM
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
const XsollaAnalytics = require('@xsolla/metrika').default;
XsollaAnalytics.init({ id: 'YOUR_COUNTER_ID', hit: true }).then((analytics) => {
analytics.hit(window.location.href);
});
IIFE
<script src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.2.3"></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
.
<script
src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2.2.3/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 |
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 for maximum reliability (especially during page unload).
Global setting:
If you want to use regularfetch
instead ofsendBeacon
for manual methods (hit
,externalLink
,elementClick
, etc.), set theuseBeacon: false
parameter during initialization:XsollaAnalytics.init({ id: 'YOUR_COUNTER_ID', useBeacon: false, // ... });
Important:
Automatic trackers (such as auto pageview, click, scroll tracking, etc.) always usesendBeacon
regardless of the global parameter.Override per event:
In any manual method (hit
,externalLink
,elementClick
, etc.), you can explicitly specify the sending method using theuseBeacon
option:analytics.hit(window.location.href, {}, false); // sends via fetch analytics.hit(window.location.href, {}, true); // sends via sendBeacon
Retries with fetch:
IfsendBeacon
is not available or fails, or if you explicitly usefetch
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 theretryOptions
parameter during initialization: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 |
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 globalextraValues
orabParams
by passing them in the data object:
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
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 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 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
{
"et": 1, // Event type (e.g., HIT, CLICK, etc.)
"library_version": "2.2.3", // 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 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 tofetch
. - The method
dfpGet
has been renamed togetFingerprintHash
. - The method
keyDfpGet
has been renamed togetFingerprintData
. - Retry logic for failed fetch requests.
- See 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 for the full list.
License
MIT © Xsolla