UNPKG

@xsolla/metrika

Version:

A lightweight integration library for Xsolla Metrics (XMTS) that simplifies user tracking and analytics setup.

413 lines (325 loc) 21.2 kB
# Xsolla Metrika [![npm version](https://img.shields.io/npm/v/@xsolla/metrika.svg)](https://www.npmjs.com/package/@xsolla/metrika) [![License](https://img.shields.io/npm/l/@xsolla/metrika.svg)](LICENSE) [![Bundle size](https://badgen.net/bundlephobia/minzip/@xsolla/metrika)](https://bundlephobia.com/result?p=@xsolla/metrika) [![Downloads](https://img.shields.io/npm/dm/@xsolla/metrika.svg)](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, 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 | | CJS | `dist/xsolla-metrika.cjs.cjs` | 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) --> <script src="https://cdn.jsdelivr.net/npm/@xsolla/metrika@2"></script> <!-- unpkg (IIFE) --> <script src="https://unpkg.com/@xsolla/metrika@2"></script> ``` > **Note:** The `@2` version range automatically resolves to the latest `2.x.x` release. This is the recommended approach for production — semver guarantees backward compatibility within a major version. --- ## 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"></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/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 | | `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 | | `getClientId` | none | `string` | Get the current client ID | | `getVisitorId` | none | `string` | Get the current visitor ID | | `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 and visitorId to links and forms to allowed domains, cleans URL after extraction | | 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": "X.Y.Z", // Library version (injected at build time) "counter_id": "YOUR_COUNTER_ID", // Your project counter ID "dfp": "fingerprint_hash", // Device fingerprint "xsollauid": "380884044985925701", // 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, "cts": 1709571234567, // Client timestamp (ms since epoch) "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.) - Chrome 80+, Safari 13.1+, Firefox 74+, Edge 80+, iOS Safari 13.4+, Samsung Internet 13+ - See [docs/browser-support.md](docs/browser-support.md) for the full list. --- ## License [MIT](LICENSE.md) © Xsolla ---