@behindthescenes/analytics 0.0.9 → 0.0.11
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 +480 -162
- package/dist/manifest.json +2 -2
- package/docs/advanced-setup.md +499 -0
- package/docs/api-reference.md +498 -0
- package/docs/frameworks.md +936 -0
- package/package.json +2 -1
|
@@ -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`
|