@kitbase/analytics 0.1.6

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 ADDED
@@ -0,0 +1,475 @@
1
+ # @kitbase/analytics
2
+
3
+ Core Kitbase Analytics SDK for TypeScript and JavaScript. Framework-agnostic — works in any browser environment.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @kitbase/analytics
9
+ # or
10
+ pnpm add @kitbase/analytics
11
+ # or
12
+ yarn add @kitbase/analytics
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Kitbase } from '@kitbase/analytics';
19
+
20
+ const kitbase = new Kitbase({
21
+ sdkKey: 'your-api-key',
22
+ debug: true,
23
+ });
24
+
25
+ // Track a custom event
26
+ await kitbase.track({
27
+ channel: 'payments',
28
+ event: 'Purchase Completed',
29
+ tags: { product_id: 'prod_123', amount: 4999 },
30
+ });
31
+ ```
32
+
33
+ ### Lite Build
34
+
35
+ For a smaller bundle without offline queue support:
36
+
37
+ ```typescript
38
+ import { KitbaseAnalytics } from '@kitbase/analytics/lite';
39
+
40
+ const kitbase = new KitbaseAnalytics({ sdkKey: 'your-api-key' });
41
+ ```
42
+
43
+ ### Script Tag (CDN)
44
+
45
+ ```html
46
+ <script>
47
+ window.KITBASE_CONFIG = { sdkKey: 'your-api-key' };
48
+ </script>
49
+ <script defer src="https://kitbase.dev/script.js"></script>
50
+ ```
51
+
52
+ The script auto-initializes and exposes `window.kitbase` for tracking events:
53
+
54
+ ```html
55
+ <script>
56
+ window.kitbase.track({
57
+ channel: 'web',
58
+ event: 'Button Clicked',
59
+ tags: { button_id: 'signup' },
60
+ });
61
+ </script>
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ ```typescript
67
+ const kitbase = new Kitbase({
68
+ // Required
69
+ sdkKey: 'your-api-key',
70
+
71
+ // Optional
72
+ debug: false,
73
+ baseUrl: 'https://api.kitbase.dev',
74
+
75
+ analytics: {
76
+ autoTrackPageViews: true, // track route changes automatically
77
+ autoTrackOutboundLinks: true, // track external link clicks
78
+ autoTrackClicks: true, // track button/link/input clicks + data-kb-track-click
79
+ autoTrackScrollDepth: true, // track max scroll depth per page
80
+ autoTrackVisibility: true, // track visibility duration via data attributes
81
+ autoTrackWebVitals: false, // track Core Web Vitals (LCP, CLS, INP, FCP, TTFB)
82
+ autoDetectFrustration: true, // detect rage clicks and dead clicks
83
+ },
84
+
85
+ offline: {
86
+ enabled: true,
87
+ maxQueueSize: 1000,
88
+ flushInterval: 30000,
89
+ flushBatchSize: 50,
90
+ maxRetries: 3,
91
+ },
92
+
93
+ botDetection: {
94
+ enabled: false,
95
+ },
96
+ });
97
+ ```
98
+
99
+ ## Auto-Tracked Events
100
+
101
+ All enabled by default. The SDK automatically tracks:
102
+
103
+ | Event | Channel | Trigger | Config |
104
+ |-------|---------|---------|--------|
105
+ | `screen_view` | `__analytics` | Page navigation (init, pushState, popstate) | `autoTrackPageViews` (default `true`) |
106
+ | `outbound_link` | `__analytics` | Click on external link | `autoTrackOutboundLinks` (default `true`) |
107
+ | `click` | `__analytics` | Click on interactive element | `autoTrackClicks` (default `true`) |
108
+ | `scroll_depth` | `__analytics` | Navigation / unload (max depth per page) | `autoTrackScrollDepth` (default `true`) |
109
+ | `rage_click` | `__analytics` | 3+ clicks within 1s in same area | `autoDetectFrustration` (default `true`) |
110
+ | `dead_click` | `__analytics` | Click with no DOM change within 1s | `autoDetectFrustration` (default `true`) |
111
+ | `web_vitals` | `__analytics` | Once per page load | `autoTrackWebVitals` (default `false`) |
112
+
113
+ Page views, clicks, outbound links, scroll depth, and frustration signals are tracked automatically. The SDK intercepts `history.pushState`/`popstate` for SPA support — no framework router integration needed.
114
+
115
+ ## Data Attribute Events
116
+
117
+ Track events from HTML using data attributes — no JavaScript needed. Works in any framework or vanilla HTML.
118
+
119
+ ### Click Tracking
120
+
121
+ Fire a named event when a user clicks an element:
122
+
123
+ ```html
124
+ <!-- Basic -->
125
+ <button data-kb-track-click="CTA Clicked">Sign Up Now</button>
126
+
127
+ <!-- With custom channel -->
128
+ <button data-kb-track-click="Add to Cart" data-kb-click-channel="ecommerce">
129
+ Add to Cart
130
+ </button>
131
+ ```
132
+
133
+ | Attribute | Required | Default | Description |
134
+ |-----------|----------|---------|-------------|
135
+ | `data-kb-track-click` | Yes | — | Event name to fire |
136
+ | `data-kb-click-channel` | No | `'engagement'` | Channel for the event |
137
+
138
+ Elements with `data-kb-track-click` skip the generic auto-click tracking to avoid double-counting. Disable with `autoTrackClicks: false`.
139
+
140
+ ### Visibility Duration
141
+
142
+ Track how long elements are visible in the viewport:
143
+
144
+ ```html
145
+ <!-- Basic -->
146
+ <section data-kb-track-visibility="Pricing Section Viewed">...</section>
147
+
148
+ <!-- With optional channel and threshold -->
149
+ <div
150
+ data-kb-track-visibility="Hero Banner Viewed"
151
+ data-kb-visibility-channel="marketing"
152
+ data-kb-visibility-threshold="0.5"
153
+ >...</div>
154
+ ```
155
+
156
+ | Attribute | Required | Default | Description |
157
+ |-----------|----------|---------|-------------|
158
+ | `data-kb-track-visibility` | Yes | — | Event name to fire |
159
+ | `data-kb-visibility-channel` | No | `'engagement'` | Channel for the event |
160
+ | `data-kb-visibility-threshold` | No | `0.5` | IntersectionObserver threshold (0–1) |
161
+
162
+ Fires an event with `duration_seconds` and `duration_ms` tags when the element leaves the viewport, is removed from the DOM, or the user navigates away. Dynamically added elements are picked up via MutationObserver. Disable with `autoTrackVisibility: false`.
163
+
164
+ ## Web Vitals
165
+
166
+ Track [Core Web Vitals](https://web.dev/vitals/) by enabling `autoTrackWebVitals`:
167
+
168
+ ```typescript
169
+ const kitbase = new Kitbase({
170
+ sdkKey: 'your-api-key',
171
+ analytics: {
172
+ autoTrackWebVitals: true,
173
+ },
174
+ });
175
+ ```
176
+
177
+ The SDK collects all 5 metrics and sends them as a single `web_vitals` event on the `__analytics` channel:
178
+
179
+ | Tag | Metric | Description |
180
+ |-----|--------|-------------|
181
+ | `__lcp` | Largest Contentful Paint | Loading performance (ms) |
182
+ | `__cls` | Cumulative Layout Shift | Visual stability (score) |
183
+ | `__inp` | Interaction to Next Paint | Interactivity (ms) |
184
+ | `__fcp` | First Contentful Paint | First render (ms) |
185
+ | `__ttfb` | Time to First Byte | Server response time (ms) |
186
+
187
+ Metrics are sent once per page load. A 30-second timeout ensures data is sent even if some metrics never fire (e.g., INP requires user interaction). Only collected metrics are included in the event tags.
188
+
189
+ ## Frustration Signals
190
+
191
+ The SDK automatically detects two types of user frustration. Enabled by default — disable with `autoDetectFrustration: false`.
192
+
193
+ ### Rage Click
194
+
195
+ Fired when 3+ clicks occur within 1 second in the same area (30px radius). Indicates the user is clicking repeatedly out of frustration.
196
+
197
+ | Tag | Type | Description |
198
+ |-----|------|-------------|
199
+ | `__selector` | `string` | CSS selector of the element |
200
+ | `__tag` | `string` | HTML tag name |
201
+ | `__id` | `string` | Element `id` attribute |
202
+ | `__class` | `string` | Element `className` |
203
+ | `__text` | `string` | Text content (first 100 chars) |
204
+ | `__click_count` | `number` | Number of rapid clicks detected |
205
+ | `__path` | `string` | Current page path |
206
+
207
+ ### Dead Click
208
+
209
+ Fired when a click on an interactive element produces no DOM change within 1 second. Indicates the user clicked something that looked interactive but had no effect.
210
+
211
+ | Tag | Type | Description |
212
+ |-----|------|-------------|
213
+ | `__selector` | `string` | CSS selector of the element |
214
+ | `__tag` | `string` | HTML tag name |
215
+ | `__id` | `string` | Element `id` attribute |
216
+ | `__class` | `string` | Element `className` |
217
+ | `__text` | `string` | Text content (first 100 chars) |
218
+ | `__path` | `string` | Current page path |
219
+
220
+ Dead click detection uses a `MutationObserver` to watch for any DOM change (child nodes, attributes, character data) after a click. If nothing changes within 1 second, the event fires.
221
+
222
+ ## Event Tracking
223
+
224
+ ### Basic Event
225
+
226
+ ```typescript
227
+ await kitbase.track({
228
+ channel: 'engagement',
229
+ event: 'Button Clicked',
230
+ });
231
+ ```
232
+
233
+ ### Event with Metadata
234
+
235
+ ```typescript
236
+ await kitbase.track({
237
+ channel: 'payments',
238
+ event: 'Subscription Started',
239
+ user_id: 'user_123',
240
+ icon: '💰',
241
+ notify: true,
242
+ description: 'New premium subscription',
243
+ tags: {
244
+ plan: 'premium',
245
+ interval: 'monthly',
246
+ amount: 1999,
247
+ },
248
+ });
249
+ ```
250
+
251
+ ### Duration Tracking
252
+
253
+ ```typescript
254
+ // Start timing
255
+ kitbase.timeEvent('Video Watched');
256
+
257
+ // ... user watches video ...
258
+
259
+ // Track with automatic duration — $duration tag included automatically
260
+ await kitbase.track({
261
+ channel: 'engagement',
262
+ event: 'Video Watched',
263
+ tags: { video_id: '123' },
264
+ });
265
+ ```
266
+
267
+ ## Web Analytics
268
+
269
+ ### Page Views
270
+
271
+ ```typescript
272
+ // Manual
273
+ await kitbase.trackPageView();
274
+
275
+ // With custom path/title
276
+ await kitbase.trackPageView({
277
+ path: '/products/123',
278
+ title: 'Product Details',
279
+ });
280
+
281
+ // Enable automatic tracking on route changes
282
+ kitbase.enableAutoPageViews();
283
+ ```
284
+
285
+ ### Revenue
286
+
287
+ ```typescript
288
+ await kitbase.trackRevenue({
289
+ amount: 4999,
290
+ currency: 'USD',
291
+ tags: { product_id: 'prod_123', coupon: 'SAVE20' },
292
+ });
293
+ ```
294
+
295
+ ## User Identification
296
+
297
+ ```typescript
298
+ // Identify a user
299
+ await kitbase.identify({
300
+ userId: 'user_123',
301
+ traits: { email: 'user@example.com', plan: 'premium' },
302
+ });
303
+
304
+ // Reset on logout
305
+ kitbase.reset();
306
+ ```
307
+
308
+ ## Super Properties
309
+
310
+ Properties included with every event:
311
+
312
+ ```typescript
313
+ kitbase.register({ app_version: '2.1.0', platform: 'web' });
314
+
315
+ // Set only if not already set
316
+ kitbase.registerOnce({ first_visit: new Date().toISOString() });
317
+
318
+ // Remove / clear
319
+ kitbase.unregister('platform');
320
+ kitbase.clearSuperProperties();
321
+ ```
322
+
323
+ ## Bot Detection
324
+
325
+ ```typescript
326
+ const kitbase = new Kitbase({
327
+ sdkKey: 'your-api-key',
328
+ botDetection: { enabled: true },
329
+ });
330
+
331
+ kitbase.isBot(); // boolean
332
+ kitbase.getBotDetectionResult(); // detailed result
333
+ kitbase.redetectBot(); // force re-run
334
+ ```
335
+
336
+ When bot detection is enabled and a bot is detected, all tracking calls are silently blocked.
337
+
338
+ ## Offline Support
339
+
340
+ Events are queued locally when offline and synced when back online:
341
+
342
+ ```typescript
343
+ const kitbase = new Kitbase({
344
+ sdkKey: 'your-api-key',
345
+ offline: { enabled: true },
346
+ });
347
+
348
+ // Check queue status
349
+ const stats = await kitbase.getQueueStats();
350
+
351
+ // Manual flush
352
+ await kitbase.flushQueue();
353
+
354
+ // Clear queue
355
+ await kitbase.clearQueue();
356
+ ```
357
+
358
+ ## Debug Mode
359
+
360
+ ```typescript
361
+ kitbase.setDebugMode(true);
362
+ kitbase.setDebugMode(false);
363
+ kitbase.isDebugMode(); // boolean
364
+ ```
365
+
366
+ ## Cleanup
367
+
368
+ ```typescript
369
+ kitbase.shutdown();
370
+ ```
371
+
372
+ Disconnects observers, flushes pending scroll depth and visibility events, and cleans up event listeners.
373
+
374
+ ## API Reference
375
+
376
+ ### Event Tracking
377
+
378
+ | Method | Description |
379
+ |--------|-------------|
380
+ | `track(options)` | Track a custom event |
381
+ | `trackPageView(options?)` | Track a page view |
382
+ | `trackRevenue(options)` | Track a revenue event |
383
+ | `trackOutboundLink(options)` | Track an outbound link click |
384
+ | `trackClick(tags)` | Track a click event |
385
+
386
+ ### User Identification
387
+
388
+ | Method | Description |
389
+ |--------|-------------|
390
+ | `identify(options)` | Identify a user with traits |
391
+ | `getUserId()` | Get the identified user ID |
392
+ | `reset()` | Reset user identity and session |
393
+
394
+ ### Super Properties
395
+
396
+ | Method | Description |
397
+ |--------|-------------|
398
+ | `register(properties)` | Set properties included in all events |
399
+ | `registerOnce(properties)` | Set properties only if not already set |
400
+ | `unregister(key)` | Remove a super property |
401
+ | `getSuperProperties()` | Get all super properties |
402
+ | `clearSuperProperties()` | Clear all super properties |
403
+
404
+ ### Time Events
405
+
406
+ | Method | Description |
407
+ |--------|-------------|
408
+ | `timeEvent(eventName)` | Start timing an event |
409
+ | `cancelTimeEvent(eventName)` | Cancel timing an event |
410
+ | `getTimedEvents()` | List all active timed events |
411
+ | `getEventDuration(eventName)` | Get elapsed time without stopping |
412
+
413
+ ### Privacy & Consent
414
+
415
+ | Method | Description |
416
+ |--------|-------------|
417
+ | `optOut()` | Opt out of tracking |
418
+ | `optIn()` | Opt in to tracking |
419
+ | `isOptedOut()` | Check if opted out |
420
+ | `hasConsent()` | Check if user has consented |
421
+
422
+ ### Bot Detection (Internal)
423
+ ### Bot Detection
424
+
425
+ | Method | Description |
426
+ |--------|-------------|
427
+ | `isBot()` | Check if current visitor is a bot |
428
+ | `getBotDetectionResult()` | Get detailed detection result |
429
+ | `redetectBot()` | Force re-run detection |
430
+
431
+ ### Debug & Lifecycle
432
+
433
+ | Method | Description |
434
+ |--------|-------------|
435
+ | `setDebugMode(enabled)` | Toggle debug logging |
436
+ | `isDebugMode()` | Check if debug mode is on |
437
+ | `enableAutoPageViews()` | Enable automatic pageview tracking |
438
+ | `shutdown()` | Flush pending events and cleanup resources |
439
+
440
+ ### Offline Queue (full build only)
441
+
442
+ | Method | Description |
443
+ |--------|-------------|
444
+ | `getQueueStats()` | Get queue size and status |
445
+ | `flushQueue()` | Manually flush the queue |
446
+ | `clearQueue()` | Clear all queued events |
447
+
448
+ ## TypeScript Support
449
+
450
+ Full TypeScript support with exported types:
451
+
452
+ ```typescript
453
+ import type {
454
+ KitbaseConfig,
455
+ TrackOptions,
456
+ TrackResponse,
457
+ PageViewOptions,
458
+ RevenueOptions,
459
+ IdentifyOptions,
460
+ AnalyticsConfig,
461
+ Tags,
462
+ TagValue,
463
+ OfflineConfig,
464
+ BotDetectionConfig,
465
+ } from '@kitbase/analytics';
466
+ ```
467
+
468
+ ## Browser Support
469
+
470
+ - Chrome, Firefox, Safari, Edge (latest versions)
471
+ - Works in Node.js 18+
472
+
473
+ ## License
474
+
475
+ MIT