@behindthescenes/analytics 0.0.9 → 0.0.10

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.
@@ -0,0 +1,498 @@
1
+ # API Reference
2
+
3
+ Complete reference for the BTS Analytics SDK.
4
+
5
+ ## Core Functions
6
+
7
+ ### `createBTSAnalytics(init)`
8
+
9
+ Creates and initializes a new BTS Analytics instance.
10
+
11
+ ```typescript
12
+ import { createBTSAnalytics } from "@behindthescenes/analytics";
13
+
14
+ const analytics = createBTSAnalytics({
15
+ siteKey: "your-public-site-key",
16
+ autoPageviews: true,
17
+ debug: false,
18
+ });
19
+ ```
20
+
21
+ **Parameters:**
22
+
23
+ | Parameter | Type | Required | Description |
24
+ |-----------|------|----------|-------------|
25
+ | `siteKey` | `string` | Yes | Your public site key from BTS |
26
+ | `endpoint` | `string` | No | Override the default endpoint |
27
+ | `autoPageviews` | `boolean` | No | Enable automatic page view tracking (default: `true`) |
28
+ | `autoTrack` | `boolean \| object` | No | Fine-grained auto-tracking control |
29
+ | `debug` | `boolean` | No | Enable debug logging (default: `false`) |
30
+ | `flushIntervalMs` | `number` | No | Event flush interval in ms (default: `300`) |
31
+ | `googleAnalytics` | `boolean \| object` | No | GA4 integration settings |
32
+ | `requestHeaders` | `HeadersInit \| function` | No | Custom request headers |
33
+
34
+ **AutoTrack Configuration:**
35
+
36
+ ```typescript
37
+ autoTrack: {
38
+ pageviews: true, // Initial page_view + SPA navigation
39
+ history: true, // pushState/replaceState hooks
40
+ outboundLinks: true, // External link clicks
41
+ buttonClicks: true, // Button interactions
42
+ formSubmissions: true, // Form submit events
43
+ search: true, // GET search forms
44
+ viewContent: true // IntersectionObserver content views
45
+ }
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Methods
51
+
52
+ ### `track(eventName, properties?)`
53
+
54
+ Track a custom event.
55
+
56
+ ```typescript
57
+ analytics.track("video_played", {
58
+ videoId: "intro-01",
59
+ duration: 120,
60
+ autoplay: false,
61
+ });
62
+ ```
63
+
64
+ **Parameters:**
65
+
66
+ | Parameter | Type | Required | Description |
67
+ |-----------|------|----------|-------------|
68
+ | `eventName` | `string` | Yes | Name of the event |
69
+ | `properties` | `object` | No | Additional event properties |
70
+
71
+ ---
72
+
73
+ ### `trackStandard(eventName, properties?)`
74
+
75
+ Track a predefined standard event.
76
+
77
+ ```typescript
78
+ analytics.trackStandard("purchase", {
79
+ orderId: "order_123",
80
+ monetaryValue: 149,
81
+ currency: "USD",
82
+ });
83
+ ```
84
+
85
+ **Standard Events:**
86
+
87
+ | Event | Type | Description |
88
+ |-------|------|-------------|
89
+ | `page_view` | Page | Page viewed |
90
+ | `view_content` | Engagement | Content viewed |
91
+ | `search` | Engagement | Search performed |
92
+ | `lead` | Conversion | Lead captured |
93
+ | `sign_up` | Conversion | User registered |
94
+ | `begin_checkout` | Conversion | Checkout started |
95
+ | `add_payment_info` | Conversion | Payment info added |
96
+ | `purchase` | Conversion | Purchase completed |
97
+ | `outbound_click` | Engagement | External link clicked |
98
+ | `button_click` | Engagement | Button clicked |
99
+ | `form_submit` | Engagement | Form submitted |
100
+
101
+ **Legacy Aliases:**
102
+
103
+ | Legacy Name | Maps To |
104
+ |-------------|---------|
105
+ | `$pageview` | `page_view` |
106
+ | `checkout_started` | `begin_checkout` |
107
+ | `lead_capture` | `lead` |
108
+ | `purchase_completed` | `purchase` |
109
+ | `registration_complete` | `sign_up` |
110
+
111
+ ---
112
+
113
+ ### `identify(userId, traits?)`
114
+
115
+ Associate events with a known user.
116
+
117
+ ```typescript
118
+ analytics.identify("user_123", {
119
+ email: "fan@example.com",
120
+ name: "John Doe",
121
+ plan: "pro",
122
+ createdAt: "2024-01-15",
123
+ });
124
+ ```
125
+
126
+ **Parameters:**
127
+
128
+ | Parameter | Type | Required | Description |
129
+ |-----------|------|----------|-------------|
130
+ | `userId` | `string` | Yes | Unique user identifier |
131
+ | `traits` | `object` | No | User attributes |
132
+
133
+ ---
134
+
135
+ ### `page(path?)`
136
+
137
+ Manually trigger a page view event.
138
+
139
+ ```typescript
140
+ // Use current URL
141
+ analytics.page();
142
+
143
+ // Specify path
144
+ analytics.page("/pricing");
145
+
146
+ // Include query params
147
+ analytics.page("/pricing?plan=pro");
148
+ ```
149
+
150
+ **Parameters:**
151
+
152
+ | Parameter | Type | Required | Description |
153
+ |-----------|------|----------|-------------|
154
+ | `path` | `string` | No | Page path (defaults to current path) |
155
+
156
+ ---
157
+
158
+ ### `startFunnel(entryPath?)`
159
+
160
+ Start a cross-site attribution journey.
161
+
162
+ ```typescript
163
+ const { journeyId, journeyToken, expiresAt } = await analytics.startFunnel("/landing");
164
+
165
+ // Use journeyToken to decorate URLs
166
+ const checkoutUrl = analytics.decorateUrl(
167
+ "https://behindthescenes.com/checkout",
168
+ journeyToken,
169
+ );
170
+ ```
171
+
172
+ **Parameters:**
173
+
174
+ | Parameter | Type | Required | Description |
175
+ |-----------|------|----------|-------------|
176
+ | `entryPath` | `string` | No | Entry point path |
177
+
178
+ **Returns:** `Promise<{ journeyId: string; journeyToken: string; expiresAt: number }>`
179
+
180
+ ---
181
+
182
+ ### `decorateUrl(url, journeyToken?)`
183
+
184
+ Append site key and journey token to a BTS URL.
185
+
186
+ ```typescript
187
+ const checkoutUrl = analytics.decorateUrl(
188
+ "https://behindthescenes.com/checkout",
189
+ journeyToken,
190
+ );
191
+ // Result: https://behindthescenes.com/checkout?bts_site=xxx&bts_jt=yyy
192
+ ```
193
+
194
+ **Parameters:**
195
+
196
+ | Parameter | Type | Required | Description |
197
+ |-----------|------|----------|-------------|
198
+ | `url` | `string` | Yes | Base URL to decorate |
199
+ | `journeyToken` | `string` | No | Journey token (uses persisted if omitted) |
200
+
201
+ **Returns:** `string` - Decorated URL
202
+
203
+ ---
204
+
205
+ ### `getPersistedJourneyToken()`
206
+
207
+ Get the currently stored journey token.
208
+
209
+ ```typescript
210
+ const token = analytics.getPersistedJourneyToken();
211
+ if (token) {
212
+ const url = analytics.decorateUrl("https://behindthescenes.com/join", token);
213
+ }
214
+ ```
215
+
216
+ **Returns:** `string | null` - Journey token or null if none exists
217
+
218
+ ---
219
+
220
+ ### `notifyHandoff(journeyToken, context?)`
221
+
222
+ Notify BTS of a journey handoff event.
223
+
224
+ ```typescript
225
+ await analytics.notifyHandoff(journeyToken, {
226
+ source: "external_landing_page",
227
+ campaign: "summer_2024",
228
+ customValue: 100,
229
+ });
230
+ ```
231
+
232
+ **Parameters:**
233
+
234
+ | Parameter | Type | Required | Description |
235
+ |-----------|------|----------|-------------|
236
+ | `journeyToken` | `string` | Yes | Journey token |
237
+ | `context` | `object` | No | Additional handoff context |
238
+
239
+ ---
240
+
241
+ ### `submitContactForm(input)`
242
+
243
+ Submit a contact form to GoHighLevel.
244
+
245
+ ```typescript
246
+ await analytics.submitContactForm({
247
+ locationId: "your-ghl-location-id",
248
+ email: "fan@example.com",
249
+ subject: "Partnership enquiry",
250
+ body: "Tell us more about working together.",
251
+ name: "Jane Smith",
252
+ phone: "+1234567890",
253
+ source: "website_contact",
254
+ tags: ["partnership", "high-value"],
255
+ customFields: {
256
+ company: "Acme Inc",
257
+ industry: "Technology",
258
+ },
259
+ metadata: {
260
+ page: window.location.pathname,
261
+ referrer: document.referrer,
262
+ },
263
+ });
264
+ ```
265
+
266
+ **Parameters:**
267
+
268
+ | Parameter | Type | Required | Description |
269
+ |-----------|------|----------|-------------|
270
+ | `locationId` | `string` | Yes | GoHighLevel location ID |
271
+ | `email` | `string` | No* | Contact email (required if no phone) |
272
+ | `phone` | `string` | No* | Contact phone (required if no email) |
273
+ | `subject` | `string` | No | Subject line |
274
+ | `body` | `string` | No | Message body |
275
+ | `name` | `string` | No | Full name |
276
+ | `firstName` | `string` | No | First name |
277
+ | `lastName` | `string` | No | Last name |
278
+ | `source` | `string` | No | Lead source (default: `behind_the_scenes`) |
279
+ | `tags` | `string[]` | No | GHL tags |
280
+ | `customFields` | `object` | No | GHL custom fields |
281
+ | `metadata` | `object` | No | BTS metadata (stored as `bts_meta_<key>`) |
282
+
283
+ **Returns:** `Promise<{ ok: boolean; data?: unknown }>`
284
+
285
+ ---
286
+
287
+ ### `flushNow()`
288
+
289
+ Immediately flush the event queue.
290
+
291
+ ```typescript
292
+ // Track event and ensure it's sent before navigation
293
+ analytics.track("checkout_cta_clicked", { placement: "hero" });
294
+ await analytics.flushNow();
295
+ window.location.href = "/checkout";
296
+ ```
297
+
298
+ **Returns:** `Promise<void>`
299
+
300
+ ---
301
+
302
+ ### `listStandardEvents()`
303
+
304
+ Get the list of supported standard event names.
305
+
306
+ ```typescript
307
+ const events = analytics.listStandardEvents();
308
+ // ["page_view", "view_content", "search", "lead", "sign_up", ...]
309
+ ```
310
+
311
+ **Returns:** `string[]` - Array of standard event names
312
+
313
+ ---
314
+
315
+ ### `destroy()`
316
+
317
+ Clean up the analytics instance.
318
+
319
+ ```typescript
320
+ // When unmounting a component or navigating away
321
+ analytics.destroy();
322
+ ```
323
+
324
+ This method:
325
+ - Removes all event listeners
326
+ - Disconnects observers
327
+ - Flushes any pending events
328
+ - Prevents further tracking
329
+
330
+ ---
331
+
332
+ ## Types
333
+
334
+ ### `BTSAnalyticsInit`
335
+
336
+ Initialization options type.
337
+
338
+ ```typescript
339
+ type BTSAnalyticsInit = {
340
+ siteKey: string;
341
+ endpoint?: string;
342
+ autoPageviews?: boolean;
343
+ autoTrack?: boolean | Partial<AutoTrackConfig>;
344
+ debug?: boolean;
345
+ flushIntervalMs?: number;
346
+ googleAnalytics?: boolean | {
347
+ loadTag?: boolean;
348
+ measurementId?: string;
349
+ };
350
+ requestHeaders?: BTSAnalyticsRequestHeaders;
351
+ };
352
+ ```
353
+
354
+ ### `BTSAnalyticsStandardEventName`
355
+
356
+ Standard event name union type.
357
+
358
+ ```typescript
359
+ type BTSAnalyticsStandardEventName =
360
+ | "page_view"
361
+ | "view_content"
362
+ | "search"
363
+ | "lead"
364
+ | "sign_up"
365
+ | "begin_checkout"
366
+ | "add_payment_info"
367
+ | "purchase"
368
+ | "outbound_click"
369
+ | "button_click"
370
+ | "form_submit";
371
+ ```
372
+
373
+ ### `BTSAnalyticsEventType`
374
+
375
+ Event type classification.
376
+
377
+ ```typescript
378
+ type BTSAnalyticsEventType = "page_view" | "custom" | "identify" | "conversion";
379
+ ```
380
+
381
+ ### `BTSAnalyticsContactFormInput`
382
+
383
+ Contact form input type.
384
+
385
+ ```typescript
386
+ type BTSAnalyticsContactFormInput = {
387
+ locationId: string;
388
+ email?: string;
389
+ phone?: string;
390
+ subject?: string;
391
+ body?: string;
392
+ name?: string;
393
+ firstName?: string;
394
+ lastName?: string;
395
+ source?: string;
396
+ tags?: string[];
397
+ customFields?: Record<string, string | number | boolean>;
398
+ metadata?: Record<string, unknown>;
399
+ };
400
+ ```
401
+
402
+ ### `BTSAnalyticsRequestContext`
403
+
404
+ Context passed to request headers callback.
405
+
406
+ ```typescript
407
+ type BTSAnalyticsRequestContext = {
408
+ body: unknown;
409
+ bodyText: string;
410
+ endpoint: string;
411
+ headers: Record<string, string>;
412
+ path: string;
413
+ siteKey: string;
414
+ url: string;
415
+ };
416
+ ```
417
+
418
+ ---
419
+
420
+ ## HTML Data Attributes
421
+
422
+ Use these data attributes for automatic tracking:
423
+
424
+ ### Content View Tracking
425
+
426
+ ```html
427
+ <article
428
+ data-bts-view-content="offer_123"
429
+ data-bts-content-type="offer"
430
+ data-bts-content-title="Creator Accelerator"
431
+ >
432
+ Content here
433
+ </article>
434
+ ```
435
+
436
+ **Attributes:**
437
+
438
+ | Attribute | Description |
439
+ |-----------|-------------|
440
+ | `data-bts-view-content` | Content identifier (required) |
441
+ | `data-bts-content-type` | Type of content (e.g., "offer", "video", "post") |
442
+ | `data-bts-content-title` | Human-readable title |
443
+ | `data-bts-content-id` | Alternative content ID |
444
+
445
+ ### Click Tracking
446
+
447
+ ```html
448
+ <button data-bts-track-click>Track this button</button>
449
+ ```
450
+
451
+ **Attributes:**
452
+
453
+ | Attribute | Description |
454
+ |-----------|-------------|
455
+ | `data-bts-track-click` | Mark element for click tracking |
456
+
457
+ ---
458
+
459
+ ## Auto-Tracked Events
460
+
461
+ Events captured automatically when `autoTrack` is enabled:
462
+
463
+ ### Page View
464
+
465
+ - **Trigger**: Initial page load, SPA navigation (pushState/replaceState/popstate)
466
+ - **Event**: `page_view`
467
+ - **Properties**: `autoCaptured: true`
468
+
469
+ ### Outbound Click
470
+
471
+ - **Trigger**: Click on `<a>` tag with different origin
472
+ - **Event**: `outbound_click`
473
+ - **Properties**: `elementHref`, `elementId`, `elementText`, `linkHost`
474
+
475
+ ### Button Click
476
+
477
+ - **Trigger**: Click on `<button>`, `[role="button"]`, or `[data-bts-track-click]`
478
+ - **Event**: `button_click`
479
+ - **Properties**: `elementId`, `elementName`, `elementRole`, `elementText`
480
+
481
+ ### Form Submit
482
+
483
+ - **Trigger**: Form submission
484
+ - **Event**: `form_submit`
485
+ - **Properties**: `formAction`, `formId`, `formMethod`, `formName`
486
+
487
+ ### Search
488
+
489
+ - **Trigger**: GET form submission with query params
490
+ - **Query Keys**: `q`, `query`, `search`
491
+ - **Event**: `search`
492
+ - **Properties**: `autoCaptured: true`, `queryKey`, `searchQuery`
493
+
494
+ ### View Content
495
+
496
+ - **Trigger**: Element with `[data-bts-view-content]` enters viewport
497
+ - **Event**: `view_content`
498
+ - **Properties**: `autoCaptured: true`, `contentId`, `contentType`, `contentTitle`