mytart 0.6.0 â 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -2
- package/dist/index.d.mts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/index.mjs +15 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- ð **
|
|
9
|
+
- ð **8 providers out of the box**: Google Analytics 4, Mixpanel, Segment, Amplitude, Plausible, PostHog, Meta Pixel, Microsoft Clarity
|
|
10
10
|
- ð **Universal**: works in Node.js, browsers, and any JS framework (Next.js, Remix, Astro, SvelteKit, etc.)
|
|
11
11
|
- ð· **TypeScript-first**: precise typings, object-parameter style for great DX
|
|
12
12
|
- ðĶ **Dual ESM/CJS output**: works with `import` and `require`
|
|
13
13
|
- ðŠķ **Lightweight**: direct HTTP via axios, no SDK overhead
|
|
14
|
+
- ðĪ **Bot filtering**: optionally ignore bots and crawlers via [ua-parser-js](https://github.com/nicolevanderhoeven/ua-parser-js)
|
|
14
15
|
- â
**Node.js âĨ 18**
|
|
15
16
|
|
|
16
17
|
## Installation
|
|
@@ -253,6 +254,64 @@ await provider.updatePixelConsent(true); // fbq('consent', 'grant')
|
|
|
253
254
|
await provider.updatePixelConsent(false); // fbq('consent', 'revoke')
|
|
254
255
|
```
|
|
255
256
|
|
|
257
|
+
### Microsoft Clarity
|
|
258
|
+
|
|
259
|
+
[Microsoft Clarity](https://clarity.microsoft.com/) is a free behavioral analytics tool that provides session recordings, heatmaps, and insights. Clarity is **browser-only** â there is no server mode.
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
{
|
|
263
|
+
provider: 'clarity',
|
|
264
|
+
projectId: 'YOUR_PROJECT_ID',
|
|
265
|
+
enabled: true,
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
When enabled:
|
|
270
|
+
|
|
271
|
+
- The official `https://www.clarity.ms/tag/{projectId}` script is loaded once on the first `track()`, `identify()`, or `page()` call
|
|
272
|
+
- `track()` fires `clarity('event', eventName)` and sets each property as a custom tag via `clarity('set', key, value)`
|
|
273
|
+
- `identify()` calls `clarity('identify', userId)` with an optional friendly name from `traits.name`, and sets remaining traits as custom tags
|
|
274
|
+
- `page()` fires a `PageView` event and sets `pageUrl`, `pageName`, and `referrer` as custom tags
|
|
275
|
+
- SSR-safe: silently succeeds when `window` is undefined
|
|
276
|
+
|
|
277
|
+
#### Cookie consent
|
|
278
|
+
|
|
279
|
+
By default Clarity operates in cookieless mode. To enable cookie-based tracking, set `cookie: true`:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
{
|
|
283
|
+
provider: 'clarity',
|
|
284
|
+
projectId: 'YOUR_PROJECT_ID',
|
|
285
|
+
cookie: true,
|
|
286
|
+
enabled: true,
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
This calls `clarity('consent')` during initialisation so Clarity can set cookies for more accurate session tracking.
|
|
291
|
+
|
|
292
|
+
## Bot Filtering
|
|
293
|
+
|
|
294
|
+
Set `ignoreBots: true` at the top level to silently drop all `track()`, `identify()`, and `page()` calls when the visitor is a known bot or crawler. Detection is powered by [`ua-parser-js`](https://github.com/nicolevanderhoeven/ua-parser-js)'s `isBot()` function.
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
const analytics = new Mytart({
|
|
298
|
+
ignoreBots: true,
|
|
299
|
+
providers: [
|
|
300
|
+
{ provider: 'google-analytics', measurementId: 'G-XXXXXXXXXX', enabled: true },
|
|
301
|
+
{ provider: 'segment', writeKey: 'YOUR_KEY', enabled: true },
|
|
302
|
+
],
|
|
303
|
+
});
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
When a bot is detected, all methods return an empty `TrackResult[]` array â no events are dispatched to any provider.
|
|
307
|
+
|
|
308
|
+
The User-Agent is read from:
|
|
309
|
+
|
|
310
|
+
1. `context.userAgent` if supplied in the `track()` call
|
|
311
|
+
2. `navigator.userAgent` in browser environments
|
|
312
|
+
|
|
313
|
+
If no User-Agent is available (e.g. server-side without `context.userAgent`), the call proceeds normally.
|
|
314
|
+
|
|
256
315
|
## API Reference
|
|
257
316
|
|
|
258
317
|
### `new Mytart(config: MytartConfig)`
|
|
@@ -263,6 +322,7 @@ interface MytartConfig {
|
|
|
263
322
|
defaultUserId?: string; // applied to every track/page call if no userId given
|
|
264
323
|
defaultAnonymousId?: string; // applied to every track/page call if no anonymousId given
|
|
265
324
|
debug?: boolean;
|
|
325
|
+
ignoreBots?: boolean; // when true, silently drops all tracking calls from known bots/crawlers
|
|
266
326
|
}
|
|
267
327
|
```
|
|
268
328
|
|
|
@@ -373,7 +433,7 @@ import type {
|
|
|
373
433
|
TrackResult, MytartError, EventContext, ProviderName, GoogleAnalyticsAppType,
|
|
374
434
|
GoogleAnalyticsConfig, ConsentSettings, ConsentState, MixpanelConfig, SegmentConfig,
|
|
375
435
|
AmplitudeConfig, PlausibleConfig, PostHogConfig, MetaPixelConfig, MetaPixelAppType,
|
|
376
|
-
MetaPixelAdvancedMatching,
|
|
436
|
+
MetaPixelAdvancedMatching, ClarityConfig,
|
|
377
437
|
} from 'mytart';
|
|
378
438
|
```
|
|
379
439
|
|
package/dist/index.d.mts
CHANGED
|
@@ -197,6 +197,17 @@ interface MytartConfig {
|
|
|
197
197
|
defaultUserId?: string;
|
|
198
198
|
defaultAnonymousId?: string;
|
|
199
199
|
debug?: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* When `true`, silently drops all `track`, `identify`, and `page` calls
|
|
202
|
+
* if the visitor's User-Agent belongs to a known bot or crawler.
|
|
203
|
+
*
|
|
204
|
+
* Detection uses `isBot()` from `ua-parser-js`. The User-Agent is read
|
|
205
|
+
* from `context.userAgent` (if supplied) or `navigator.userAgent` in
|
|
206
|
+
* browser environments.
|
|
207
|
+
*
|
|
208
|
+
* Defaults to `false` (bots are tracked like any other visitor).
|
|
209
|
+
*/
|
|
210
|
+
ignoreBots?: boolean;
|
|
200
211
|
}
|
|
201
212
|
interface EventContext {
|
|
202
213
|
ip?: string;
|
|
@@ -249,6 +260,11 @@ declare class Mytart {
|
|
|
249
260
|
private readonly providers;
|
|
250
261
|
private readonly config;
|
|
251
262
|
constructor(config: MytartConfig);
|
|
263
|
+
/**
|
|
264
|
+
* Returns `true` when `ignoreBots` is enabled and the given (or detected)
|
|
265
|
+
* User-Agent belongs to a known bot or crawler.
|
|
266
|
+
*/
|
|
267
|
+
private isBotRequest;
|
|
252
268
|
track(options: TrackOptions): Promise<TrackResult[]>;
|
|
253
269
|
identify(options: IdentifyOptions): Promise<TrackResult[]>;
|
|
254
270
|
page(options: PageOptions): Promise<TrackResult[]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -197,6 +197,17 @@ interface MytartConfig {
|
|
|
197
197
|
defaultUserId?: string;
|
|
198
198
|
defaultAnonymousId?: string;
|
|
199
199
|
debug?: boolean;
|
|
200
|
+
/**
|
|
201
|
+
* When `true`, silently drops all `track`, `identify`, and `page` calls
|
|
202
|
+
* if the visitor's User-Agent belongs to a known bot or crawler.
|
|
203
|
+
*
|
|
204
|
+
* Detection uses `isBot()` from `ua-parser-js`. The User-Agent is read
|
|
205
|
+
* from `context.userAgent` (if supplied) or `navigator.userAgent` in
|
|
206
|
+
* browser environments.
|
|
207
|
+
*
|
|
208
|
+
* Defaults to `false` (bots are tracked like any other visitor).
|
|
209
|
+
*/
|
|
210
|
+
ignoreBots?: boolean;
|
|
200
211
|
}
|
|
201
212
|
interface EventContext {
|
|
202
213
|
ip?: string;
|
|
@@ -249,6 +260,11 @@ declare class Mytart {
|
|
|
249
260
|
private readonly providers;
|
|
250
261
|
private readonly config;
|
|
251
262
|
constructor(config: MytartConfig);
|
|
263
|
+
/**
|
|
264
|
+
* Returns `true` when `ignoreBots` is enabled and the given (or detected)
|
|
265
|
+
* User-Agent belongs to a known bot or crawler.
|
|
266
|
+
*/
|
|
267
|
+
private isBotRequest;
|
|
252
268
|
track(options: TrackOptions): Promise<TrackResult[]>;
|
|
253
269
|
identify(options: IdentifyOptions): Promise<TrackResult[]>;
|
|
254
270
|
page(options: PageOptions): Promise<TrackResult[]>;
|
package/dist/index.js
CHANGED
|
@@ -43,6 +43,9 @@ __export(index_exports, {
|
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(index_exports);
|
|
45
45
|
|
|
46
|
+
// src/mytart.ts
|
|
47
|
+
var import_bot_detection = require("ua-parser-js/bot-detection");
|
|
48
|
+
|
|
46
49
|
// src/providers/base.ts
|
|
47
50
|
var BaseProvider = class {
|
|
48
51
|
/**
|
|
@@ -1224,7 +1227,17 @@ var Mytart = class {
|
|
|
1224
1227
|
this.config = config;
|
|
1225
1228
|
this.providers = config.providers.filter((c) => c.enabled === true).map(createProvider);
|
|
1226
1229
|
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Returns `true` when `ignoreBots` is enabled and the given (or detected)
|
|
1232
|
+
* User-Agent belongs to a known bot or crawler.
|
|
1233
|
+
*/
|
|
1234
|
+
isBotRequest(userAgent) {
|
|
1235
|
+
if (!this.config.ignoreBots) return false;
|
|
1236
|
+
const ua = userAgent ?? (typeof navigator !== "undefined" ? navigator.userAgent : void 0);
|
|
1237
|
+
return ua ? (0, import_bot_detection.isBot)(ua) : false;
|
|
1238
|
+
}
|
|
1227
1239
|
async track(options) {
|
|
1240
|
+
if (this.isBotRequest(options.context?.userAgent)) return [];
|
|
1228
1241
|
const enriched = {
|
|
1229
1242
|
userId: this.config.defaultUserId,
|
|
1230
1243
|
anonymousId: this.config.defaultAnonymousId,
|
|
@@ -1233,9 +1246,11 @@ var Mytart = class {
|
|
|
1233
1246
|
return Promise.all(this.providers.map((p) => p.track(enriched)));
|
|
1234
1247
|
}
|
|
1235
1248
|
async identify(options) {
|
|
1249
|
+
if (this.isBotRequest()) return [];
|
|
1236
1250
|
return Promise.all(this.providers.map((p) => p.identify(options)));
|
|
1237
1251
|
}
|
|
1238
1252
|
async page(options) {
|
|
1253
|
+
if (this.isBotRequest()) return [];
|
|
1239
1254
|
const enriched = {
|
|
1240
1255
|
userId: this.config.defaultUserId,
|
|
1241
1256
|
anonymousId: this.config.defaultAnonymousId,
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/mytart.ts
|
|
2
|
+
import { isBot } from "ua-parser-js/bot-detection";
|
|
3
|
+
|
|
1
4
|
// src/providers/base.ts
|
|
2
5
|
var BaseProvider = class {
|
|
3
6
|
/**
|
|
@@ -1179,7 +1182,17 @@ var Mytart = class {
|
|
|
1179
1182
|
this.config = config;
|
|
1180
1183
|
this.providers = config.providers.filter((c) => c.enabled === true).map(createProvider);
|
|
1181
1184
|
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Returns `true` when `ignoreBots` is enabled and the given (or detected)
|
|
1187
|
+
* User-Agent belongs to a known bot or crawler.
|
|
1188
|
+
*/
|
|
1189
|
+
isBotRequest(userAgent) {
|
|
1190
|
+
if (!this.config.ignoreBots) return false;
|
|
1191
|
+
const ua = userAgent ?? (typeof navigator !== "undefined" ? navigator.userAgent : void 0);
|
|
1192
|
+
return ua ? isBot(ua) : false;
|
|
1193
|
+
}
|
|
1182
1194
|
async track(options) {
|
|
1195
|
+
if (this.isBotRequest(options.context?.userAgent)) return [];
|
|
1183
1196
|
const enriched = {
|
|
1184
1197
|
userId: this.config.defaultUserId,
|
|
1185
1198
|
anonymousId: this.config.defaultAnonymousId,
|
|
@@ -1188,9 +1201,11 @@ var Mytart = class {
|
|
|
1188
1201
|
return Promise.all(this.providers.map((p) => p.track(enriched)));
|
|
1189
1202
|
}
|
|
1190
1203
|
async identify(options) {
|
|
1204
|
+
if (this.isBotRequest()) return [];
|
|
1191
1205
|
return Promise.all(this.providers.map((p) => p.identify(options)));
|
|
1192
1206
|
}
|
|
1193
1207
|
async page(options) {
|
|
1208
|
+
if (this.isBotRequest()) return [];
|
|
1194
1209
|
const enriched = {
|
|
1195
1210
|
userId: this.config.defaultUserId,
|
|
1196
1211
|
anonymousId: this.config.defaultAnonymousId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mytart",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Multi-Yield Tracking & Analytics Relay Tool â framework-agnostic analytics for any project",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"analytics",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"node": ">=18"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"axios": "^1.7.0"
|
|
38
|
+
"axios": "^1.7.0",
|
|
39
|
+
"ua-parser-js": "^2.0.9"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@types/jest": "^29.5.0",
|