@dotcms/analytics 1.2.0-next.10 → 1.2.0-next.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 CHANGED
@@ -79,6 +79,67 @@ pageView(customData?: Record<string, unknown>): void
79
79
  - **React**: In development (API may change)
80
80
  - Custom data is optional and gets attached to the pageview event under the `custom` property alongside all automatically captured data.
81
81
 
82
+ ### Conversion Tracking
83
+
84
+ The `conversion()` method tracks user conversions (purchases, downloads, sign-ups, etc.) from your application.
85
+
86
+ **⚠️ IMPORTANT: Conversion events are business events that should only be tracked after a successful action or completed goal.** Tracking conversions on clicks or attempts (before success) diminishes their value as conversion metrics. Only track conversions when:
87
+
88
+ - ✅ Purchase is completed and payment is confirmed
89
+ - ✅ Download is successfully completed
90
+ - ✅ Sign-up form is submitted and account is created
91
+ - ✅ Form submission is successful and data is saved
92
+ - ✅ Any business goal is actually achieved
93
+
94
+ **Method signature:**
95
+
96
+ ```typescript
97
+ conversion(name: string): void
98
+ conversion(name: string, options?: Record<string, unknown>): void
99
+ ```
100
+
101
+ **Usage examples:**
102
+
103
+ ```typescript
104
+ // Basic conversion tracking (after successful download)
105
+ analytics.conversion('download');
106
+
107
+ // Conversion with custom metadata (after successful purchase)
108
+ analytics.conversion('purchase', {
109
+ value: 99.99,
110
+ currency: 'USD',
111
+ category: 'ecommerce',
112
+ productId: 'SKU-12345'
113
+ });
114
+
115
+ // Conversion with additional context (after successful signup)
116
+ analytics.conversion('signup', {
117
+ source: 'homepage',
118
+ plan: 'premium'
119
+ });
120
+ ```
121
+
122
+ **Event payload structure:**
123
+
124
+ ```json
125
+ {
126
+ "event_type": "conversion",
127
+ "local_time": "2025-10-01T16:08:33-04:00",
128
+ "data": {
129
+ "conversion": { "name": "download" },
130
+ "page": { "url": "...", "title": "..." },
131
+ "custom": { "value": 99.99, "currency": "USD", "source": "homepage" }
132
+ }
133
+ }
134
+ ```
135
+
136
+ **Important:**
137
+
138
+ - `name` is required and identifies the conversion type
139
+ - All properties in `options` go into the `custom` object
140
+ - Page data (url, title) is automatically added by the SDK
141
+ - **Only track conversions after successful completion of business goals**
142
+
82
143
  ### Custom Events
83
144
 
84
145
  The `track()` method allows you to track any custom user action with a unique event name and optional properties.
@@ -91,7 +152,7 @@ track(eventName: string, properties?: Record<string, unknown>): void
91
152
 
92
153
  **Important:**
93
154
 
94
- - `eventName` cannot be `"pageview"` (reserved for page view tracking)
155
+ - `eventName` cannot be `"pageview"` or `"conversion"` (reserved for specific tracking methods)
95
156
  - `eventName` should be a descriptive string like `"button-click"`, `"form-submit"`, `"video-play"`, etc.
96
157
  - `properties` is optional and can contain any custom data relevant to the event
97
158
 
@@ -487,10 +548,18 @@ interface DotCMSAnalytics {
487
548
 
488
549
  /**
489
550
  * Track a custom event
490
- * @param eventName - Name of the custom event (cannot be "pageview")
551
+ * @param eventName - Name of the custom event (cannot be "pageview" or "conversion")
491
552
  * @param properties - Optional object with event-specific properties
492
553
  */
493
554
  track: (eventName: string, properties?: Record<string, unknown>) => void;
555
+
556
+ /**
557
+ * Track a conversion event (purchase, download, sign-up, etc.)
558
+ * ⚠️ IMPORTANT: Only track conversions after successful completion of business goals
559
+ * @param name - Name of the conversion (e.g., "purchase", "download", "signup")
560
+ * @param options - Optional object with conversion metadata (all properties go into custom object)
561
+ */
562
+ conversion: (name: string, options?: Record<string, unknown>) => void;
494
563
  }
495
564
  ```
496
565
 
@@ -580,6 +649,52 @@ When you call `track(eventName, properties)`, the following structure is sent:
580
649
  }
581
650
  ```
582
651
 
652
+ ### Conversion Event Structure
653
+
654
+ When you call `conversion(name, options)`, the following structure is sent:
655
+
656
+ ```typescript
657
+ {
658
+ context: {
659
+ site_key: string; // Your site key
660
+ session_id: string; // Current session ID
661
+ user_id: string; // Anonymous user ID
662
+ device: { // 🤖 AUTOMATIC - Device & Browser Info
663
+ screen_resolution: string; // Screen size
664
+ language: string; // Browser language
665
+ viewport_width: string; // Viewport width
666
+ viewport_height: string; // Viewport height
667
+ }
668
+ },
669
+ events: [{
670
+ event_type: "conversion",
671
+ local_time: string, // ISO 8601 timestamp
672
+ data: {
673
+ conversion: { // 🤖 AUTOMATIC - Conversion Info
674
+ name: string; // Your conversion name
675
+ },
676
+ page: { // 🤖 AUTOMATIC - Page Information
677
+ url: string; // Full URL
678
+ title: string; // Page title
679
+ },
680
+ custom?: { // 👤 YOUR DATA (optional)
681
+ // All properties from options parameter
682
+ value?: number;
683
+ currency?: string;
684
+ category?: string;
685
+ // ... any other custom properties
686
+ }
687
+ }
688
+ }]
689
+ }
690
+ ```
691
+
692
+ **Key Points:**
693
+
694
+ - 🤖 Conversion name and page data are captured **automatically**
695
+ - 👤 All properties in `options` go into the `custom` object
696
+ - ⚠️ **Only track conversions after successful completion of business goals**
697
+
583
698
  ## Under the Hood
584
699
 
585
700
  ### Storage Keys
@@ -1,63 +1,84 @@
1
- import { Analytics as c } from "analytics";
2
- import { ANALYTICS_WINDOWS_ACTIVE_KEY as r, ANALYTICS_WINDOWS_CLEANUP_KEY as l } from "../../uve/src/internal/constants.js";
3
- import { dotAnalyticsClickPlugin as d } from "./plugin/click/dot-analytics.click.plugin.js";
1
+ import { Analytics as l } from "analytics";
2
+ import { ANALYTICS_WINDOWS_ACTIVE_KEY as a, ANALYTICS_WINDOWS_CLEANUP_KEY as d } from "../../uve/src/internal/constants.js";
3
+ import { dotAnalyticsClickPlugin as y } from "./plugin/click/dot-analytics.click.plugin.js";
4
4
  import { dotAnalyticsEnricherPlugin as m } from "./plugin/enricher/dot-analytics.enricher.plugin.js";
5
5
  import { dotAnalyticsIdentityPlugin as u } from "./plugin/identity/dot-analytics.identity.plugin.js";
6
6
  import { dotAnalyticsImpressionPlugin as p } from "./plugin/impression/dot-analytics.impression.plugin.js";
7
- import { dotAnalytics as y } from "./plugin/main/dot-analytics.plugin.js";
8
- import { validateAnalyticsConfig as A, getEnhancedTrackingPlugins as f } from "./shared/utils/dot-analytics.utils.js";
9
- import { cleanupActivityTracking as w } from "./plugin/identity/dot-analytics.identity.activity-tracker.js";
10
- const v = (n) => {
11
- const o = A(n);
12
- if (o)
7
+ import { dotAnalytics as A } from "./plugin/main/dot-analytics.plugin.js";
8
+ import { DotCMSPredefinedEventType as f } from "./shared/constants/dot-analytics.constants.js";
9
+ import { validateAnalyticsConfig as C, getEnhancedTrackingPlugins as w } from "./shared/utils/dot-analytics.utils.js";
10
+ import { cleanupActivityTracking as g } from "./plugin/identity/dot-analytics.identity.activity-tracker.js";
11
+ const _ = (t) => {
12
+ const e = C(t);
13
+ if (e)
13
14
  return console.error(
14
- `DotCMS Analytics [Core]: Missing ${o.join(" and ")} in configuration`
15
- ), typeof window < "u" && (window[r] = !1), null;
16
- const a = f(
17
- n,
15
+ `DotCMS Analytics [Core]: Missing ${e.join(" and ")} in configuration`
16
+ ), typeof window < "u" && (window[a] = !1), null;
17
+ const s = w(
18
+ t,
18
19
  p,
19
- d
20
- ), i = c({
20
+ y
21
+ ), i = l({
21
22
  app: "dotAnalytics",
22
- debug: n.debug,
23
+ debug: t.debug,
23
24
  plugins: [
24
- u(n),
25
+ u(t),
25
26
  // Inject identity context
26
- ...a,
27
+ ...s,
27
28
  //Track content impressions & clicks (conditionally loaded)
28
29
  m(),
29
30
  // Enrich and clean payload with page, device, utm data and custom data
30
- y(n)
31
+ A(t)
31
32
  // Send events to server
32
33
  ]
33
- }), e = () => w();
34
- return typeof window < "u" && (window.addEventListener("beforeunload", e), window[l] = e, window[r] = !0, window.dispatchEvent(new CustomEvent("dotcms:analytics:ready"))), {
34
+ }), r = () => g();
35
+ return typeof window < "u" && (window.addEventListener("beforeunload", r), window[d] = r, window[a] = !0, window.dispatchEvent(new CustomEvent("dotcms:analytics:ready"))), {
35
36
  /**
36
37
  * Track a page view.
37
38
  * Session activity is automatically updated by the identity plugin.
38
39
  * @param payload - Optional custom data to include with the page view (any valid JSON object)
39
40
  */
40
- pageView: (t = {}) => {
41
+ pageView: (n = {}) => {
41
42
  if (!i) {
42
43
  console.warn("DotCMS Analytics [Core]: Analytics instance not initialized");
43
44
  return;
44
45
  }
45
- i.page(t);
46
+ i.page(n);
46
47
  },
47
48
  /**
48
49
  * Track a custom event.
49
50
  * @param eventName - The name of the event to track
50
51
  * @param payload - Custom data to include with the event (any valid JSON object)
51
52
  */
52
- track: (t, s = {}) => {
53
+ track: (n, o = {}) => {
53
54
  if (!i) {
54
55
  console.warn("DotCMS Analytics [Core]: Analytics instance not initialized");
55
56
  return;
56
57
  }
57
- i.track(t, s);
58
+ i.track(n, o);
59
+ },
60
+ /**
61
+ * Track a conversion event.
62
+ * @param name - Name of the conversion (e.g., 'purchase', 'download', 'signup')
63
+ * @param options - Optional custom data
64
+ */
65
+ conversion: (n, o = {}) => {
66
+ if (!i) {
67
+ console.warn("DotCMS Analytics [Core]: Analytics instance not initialized");
68
+ return;
69
+ }
70
+ if (!n || n.trim() === "") {
71
+ console.warn("DotCMS Analytics [Core]: Conversion name cannot be empty");
72
+ return;
73
+ }
74
+ const c = {
75
+ name: n,
76
+ ...Object.keys(o).length > 0 && { custom: o }
77
+ };
78
+ i.track(f.CONVERSION, c);
58
79
  }
59
80
  };
60
81
  };
61
82
  export {
62
- v as initializeContentAnalytics
83
+ _ as initializeContentAnalytics
63
84
  };
@@ -1,4 +1,4 @@
1
- import { DotCMSPredefinedEventType as n } from "../../shared/constants/dot-analytics.constants.js";
1
+ import { DotCMSPredefinedEventType as r } from "../../shared/constants/dot-analytics.constants.js";
2
2
  import { getLocalTime as i, enrichPagePayloadOptimized as o } from "../../shared/utils/dot-analytics.utils.js";
3
3
  const l = () => ({
4
4
  name: "enrich-dot-analytics",
@@ -8,12 +8,12 @@ const l = () => ({
8
8
  * @returns {EnrichedAnalyticsPayload} Enriched payload ready for event creation
9
9
  */
10
10
  "page:dot-analytics": ({
11
- payload: t
11
+ payload: e
12
12
  }) => {
13
- const e = o(t);
14
- if (!e.page)
13
+ const t = o(e);
14
+ if (!t.page)
15
15
  throw new Error("DotCMS Analytics: Missing required page data");
16
- return e;
16
+ return t;
17
17
  },
18
18
  /**
19
19
  * TRACK EVENT ENRICHMENT - Runs after identity context injection
@@ -23,19 +23,19 @@ const l = () => ({
23
23
  * @returns {EnrichedTrackPayload} Enriched payload ready for event structuring
24
24
  */
25
25
  "track:dot-analytics": ({
26
- payload: t
26
+ payload: e
27
27
  }) => {
28
- const { event: e } = t, r = i();
29
- return e === n.CONTENT_IMPRESSION || e === n.CONTENT_CLICK ? {
30
- ...t,
28
+ const { event: t } = e, n = i();
29
+ return t === r.CONTENT_IMPRESSION || t === r.CONTENT_CLICK || t === r.CONVERSION ? {
30
+ ...e,
31
31
  page: {
32
32
  title: document.title,
33
33
  url: window.location.href
34
34
  },
35
- local_time: r
35
+ local_time: n
36
36
  } : {
37
- ...t,
38
- local_time: r
37
+ ...e,
38
+ local_time: n
39
39
  };
40
40
  }
41
41
  });
@@ -2,8 +2,8 @@ import { getUVEState as m } from "../../../../uve/src/lib/core/core.utils.js";
2
2
  import "../../../../uve/src/internal/constants.js";
3
3
  import { getViewportMetrics as d, isElementMeetingVisibilityThreshold as u } from "./dot-analytics.impression.utils.js";
4
4
  import { DEFAULT_IMPRESSION_CONFIG as l, IMPRESSION_EVENT_TYPE as g } from "../../shared/constants/dot-analytics.constants.js";
5
- import { createPluginLogger as p, isBrowser as a, findContentlets as b, extractContentletIdentifier as c, createContentletObserver as f, extractContentletData as v } from "../../shared/utils/dot-analytics.utils.js";
6
- class C {
5
+ import { createPluginLogger as p, isBrowser as a, INITIAL_SCAN_DELAY_MS as f, findContentlets as b, extractContentletIdentifier as c, createContentletObserver as v, extractContentletData as I } from "../../shared/utils/dot-analytics.utils.js";
6
+ class E {
7
7
  constructor(e) {
8
8
  this.observer = null, this.mutationObserver = null, this.elementImpressionStates = /* @__PURE__ */ new Map(), this.sessionTrackedImpressions = /* @__PURE__ */ new Set(), this.currentPagePath = "", this.subscribers = /* @__PURE__ */ new Set(), this.logger = p("Impression", e), this.impressionConfig = this.resolveImpressionConfig(e.impressions);
9
9
  }
@@ -43,7 +43,9 @@ class C {
43
43
  this.logger.warn("Impression tracking disabled in editor mode");
44
44
  return;
45
45
  }
46
- this.initializeIntersectionObserver(), this.findAndObserveContentletElements(), this.initializeDynamicContentDetector(), this.initializePageVisibilityHandler(), this.initializePageNavigationHandler(), this.logger.info("Impression tracking initialized with config:", this.impressionConfig);
46
+ this.initializeIntersectionObserver(), typeof window < "u" && setTimeout(() => {
47
+ this.logger.debug("Running initial scan after timeout..."), this.findAndObserveContentletElements();
48
+ }, f), this.initializeDynamicContentDetector(), this.initializePageVisibilityHandler(), this.initializePageNavigationHandler(), this.logger.info("Impression tracking initialized with config:", this.impressionConfig);
47
49
  }
48
50
  }
49
51
  /** Sets up IntersectionObserver with configured visibility threshold */
@@ -90,7 +92,7 @@ class C {
90
92
  }
91
93
  /** Watches for new contentlets added to DOM (debounced for performance) */
92
94
  initializeDynamicContentDetector() {
93
- a() && (this.mutationObserver = f(() => {
95
+ a() && (this.mutationObserver = v(() => {
94
96
  this.findAndObserveContentletElements();
95
97
  }), this.logger.info("MutationObserver enabled for dynamic content detection"));
96
98
  }
@@ -148,7 +150,7 @@ class C {
148
150
  trackAndSendImpression(e, i) {
149
151
  const t = this.elementImpressionStates.get(e);
150
152
  if (!t) return;
151
- const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n = v(i), r = d(i), o = parseInt(i.dataset.dotAnalyticsDomIndex || "-1", 10), h = {
153
+ const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n = I(i), r = d(i), o = parseInt(i.dataset.dotAnalyticsDomIndex || "-1", 10), h = {
152
154
  content: {
153
155
  identifier: n.identifier,
154
156
  inode: n.inode,
@@ -196,5 +198,5 @@ class C {
196
198
  }
197
199
  }
198
200
  export {
199
- C as DotCMSImpressionTracker
201
+ E as DotCMSImpressionTracker
200
202
  };
@@ -1,21 +1,21 @@
1
- import { DotCMSPredefinedEventType as c } from "../../shared/constants/dot-analytics.constants.js";
2
- import { sendAnalyticsEvent as f } from "../../shared/http/dot-analytics.http.js";
1
+ import { DotCMSPredefinedEventType as r } from "../../shared/constants/dot-analytics.constants.js";
2
+ import { sendAnalyticsEvent as N } from "../../shared/http/dot-analytics.http.js";
3
3
  import { createAnalyticsQueue as w } from "../../shared/queue/dot-analytics.queue.utils.js";
4
- const _ = (l) => {
4
+ const _ = (d) => {
5
5
  let u = !1;
6
- const m = l.queue !== !1;
7
- let d = null;
8
- const y = (e) => {
9
- const n = e.events[0], t = e.context;
10
- m && d ? d.enqueue(n, t) : f(e, l);
6
+ const m = d.queue !== !1;
7
+ let p = null;
8
+ const v = (e) => {
9
+ const c = e.events[0], t = e.context;
10
+ m && p ? p.enqueue(c, t) : N(e, d);
11
11
  };
12
12
  return {
13
13
  name: "dot-analytics",
14
- config: l,
14
+ config: d,
15
15
  /**
16
16
  * Initialize the plugin with optional queue management
17
17
  */
18
- initialize: () => (u = !0, m && (d = w(l), d.initialize()), Promise.resolve()),
18
+ initialize: () => (u = !0, m && (p = w(d), p.initialize()), Promise.resolve()),
19
19
  /**
20
20
  * Track a page view event
21
21
  * Receives enriched payload from the enricher plugin and structures it into a pageview event
@@ -23,24 +23,24 @@ const _ = (l) => {
23
23
  page: ({ payload: e }) => {
24
24
  if (!u)
25
25
  throw new Error("DotCMS Analytics: Plugin not initialized");
26
- const { context: n, page: t, utm: p, custom: i, local_time: o } = e;
26
+ const { context: c, page: t, utm: E, custom: s, local_time: a } = e;
27
27
  if (!t)
28
28
  throw new Error("DotCMS Analytics: Missing required page data");
29
- const v = {
30
- context: n,
29
+ const y = {
30
+ context: c,
31
31
  events: [
32
32
  {
33
- event_type: c.PAGEVIEW,
34
- local_time: o,
33
+ event_type: r.PAGEVIEW,
34
+ local_time: a,
35
35
  data: {
36
36
  page: t,
37
- ...p && { utm: p },
38
- ...i && { custom: i }
37
+ ...E && { utm: E },
38
+ ...s && { custom: s }
39
39
  }
40
40
  }
41
41
  ]
42
42
  };
43
- y(v);
43
+ v(y);
44
44
  },
45
45
  /**
46
46
  * Track a custom or predefined event
@@ -53,44 +53,59 @@ const _ = (l) => {
53
53
  track: ({ payload: e }) => {
54
54
  if (!u)
55
55
  throw new Error("DotCMS Analytics: Plugin not initialized");
56
- const { event: n, properties: t, context: p, local_time: i } = e;
57
- let o;
58
- switch (n) {
59
- case c.CONTENT_IMPRESSION: {
60
- const E = t, { content: s, position: a } = E, { page: r } = e;
61
- if (!s || !a || !r)
56
+ const { event: c, properties: t, context: E, local_time: s } = e;
57
+ let a;
58
+ switch (c) {
59
+ case r.CONTENT_IMPRESSION: {
60
+ const l = t, { content: n, position: i } = l, { page: o } = e;
61
+ if (!n || !i || !o)
62
62
  throw new Error("DotCMS Analytics: Missing required impression data");
63
- o = {
64
- event_type: c.CONTENT_IMPRESSION,
65
- local_time: i,
63
+ a = {
64
+ event_type: r.CONTENT_IMPRESSION,
65
+ local_time: s,
66
66
  data: {
67
- content: s,
68
- position: a,
69
- page: r
67
+ content: n,
68
+ position: i,
69
+ page: o
70
70
  }
71
71
  };
72
72
  break;
73
73
  }
74
- case c.CONTENT_CLICK: {
75
- const E = t, { content: s, position: a, element: r } = E, { page: C } = e;
76
- if (!s || !a || !r || !C)
74
+ case r.CONTENT_CLICK: {
75
+ const l = t, { content: n, position: i, element: o } = l, { page: C } = e;
76
+ if (!n || !i || !o || !C)
77
77
  throw new Error("DotCMS Analytics: Missing required click data");
78
- o = {
79
- event_type: c.CONTENT_CLICK,
80
- local_time: i,
78
+ a = {
79
+ event_type: r.CONTENT_CLICK,
80
+ local_time: s,
81
81
  data: {
82
- content: s,
83
- position: a,
84
- element: r,
82
+ content: n,
83
+ position: i,
84
+ element: o,
85
85
  page: C
86
86
  }
87
87
  };
88
88
  break;
89
89
  }
90
+ case r.CONVERSION: {
91
+ const l = t, { name: n, custom: i } = l, { page: o } = e;
92
+ if (!n || !o)
93
+ throw new Error("DotCMS Analytics: Missing required conversion data");
94
+ a = {
95
+ event_type: r.CONVERSION,
96
+ local_time: s,
97
+ data: {
98
+ conversion: { name: n },
99
+ page: o,
100
+ ...i && { custom: i }
101
+ }
102
+ };
103
+ break;
104
+ }
90
105
  default: {
91
- o = {
92
- event_type: n,
93
- local_time: i,
106
+ a = {
107
+ event_type: c,
108
+ local_time: s,
94
109
  data: {
95
110
  custom: t
96
111
  }
@@ -98,9 +113,9 @@ const _ = (l) => {
98
113
  break;
99
114
  }
100
115
  }
101
- y({
102
- context: p,
103
- events: [o]
116
+ v({
117
+ context: E,
118
+ events: [a]
104
119
  });
105
120
  },
106
121
  /**
@@ -9,6 +9,7 @@ export declare const DotCMSPredefinedEventType: {
9
9
  readonly PAGEVIEW: "pageview";
10
10
  readonly CONTENT_IMPRESSION: "content_impression";
11
11
  readonly CONTENT_CLICK: "content_click";
12
+ readonly CONVERSION: "conversion";
12
13
  };
13
14
  /**
14
15
  * Type for structured events
@@ -1,7 +1,8 @@
1
1
  const I = "/api/v1/analytics/content/event", c = {
2
2
  PAGEVIEW: "pageview",
3
3
  CONTENT_IMPRESSION: "content_impression",
4
- CONTENT_CLICK: "content_click"
4
+ CONTENT_CLICK: "content_click",
5
+ CONVERSION: "conversion"
5
6
  }, s = [
6
7
  "utm_source",
7
8
  "utm_medium",
@@ -27,13 +28,13 @@ const I = "/api/v1/analytics/content/event", c = {
27
28
  dwellMs: T,
28
29
  maxNodes: n,
29
30
  throttleMs: S
30
- }, U = "content_impression", M = "content_click", D = 300, a = "a, button", R = "dotcms-analytics-contentlet";
31
+ }, U = "content_impression", M = "content_click", D = 300, R = "a, button", a = "dotcms-analytics-contentlet";
31
32
  export {
32
33
  L as ACTIVITY_EVENTS,
33
- R as ANALYTICS_CONTENTLET_CLASS,
34
+ a as ANALYTICS_CONTENTLET_CLASS,
34
35
  I as ANALYTICS_ENDPOINT,
35
36
  i as ANALYTICS_JS_DEFAULT_PROPERTIES,
36
- a as CLICKABLE_ELEMENTS_SELECTOR,
37
+ R as CLICKABLE_ELEMENTS_SELECTOR,
37
38
  M as CLICK_EVENT_TYPE,
38
39
  D as DEFAULT_CLICK_THROTTLE_MS,
39
40
  C as DEFAULT_IMPRESSION_CONFIG,
@@ -50,6 +50,24 @@ export type DotCMSCustomEventData = {
50
50
  /** Custom data associated with the event (any valid JSON) */
51
51
  custom: JsonObject;
52
52
  };
53
+ /**
54
+ * Element information for analytics events.
55
+ * Base type for element metadata in click and conversion events.
56
+ */
57
+ export type DotCMSElementData = {
58
+ /** Text content of the element */
59
+ text: string;
60
+ /** Type of element (anchor, button, input, etc.) */
61
+ type: string;
62
+ /** Element ID (required by backend, empty string if not present) */
63
+ id: string;
64
+ /** Element classes (required by backend, empty string if not present) */
65
+ class: string;
66
+ /** Link destination as written in HTML (relative path, only for <a> elements, empty string for buttons) */
67
+ href: string;
68
+ /** Additional element attributes in key:value format (e.g., ['data-category:val', 'data-campaign:val2']) */
69
+ attributes: string[];
70
+ };
53
71
  /**
54
72
  * Partial content impression data sent by producer plugins.
55
73
  * Contains only impression-specific data (content and position).
@@ -81,20 +99,17 @@ export type DotCMSContentImpressionPayload = {
81
99
  */
82
100
  export type DotCMSContentClickPayload = DotCMSContentImpressionPayload & {
83
101
  /** Clicked element information */
84
- element: {
85
- /** Text content of the element */
86
- text: string;
87
- /** Type of element (anchor, button, etc.) */
88
- type: string;
89
- /** Element ID (required by backend, empty string if not present) */
90
- id: string;
91
- /** Element classes (required by backend, empty string if not present) */
92
- class: string;
93
- /** Link destination as written in HTML (relative path, only for <a> elements, empty string for buttons) */
94
- href: string;
95
- /** Additional element attributes in key:value format (e.g., ['data-category:val', 'data-campaign:val2']) */
96
- attributes: string[];
97
- };
102
+ element: DotCMSElementData;
103
+ };
104
+ /**
105
+ * Conversion payload sent when tracking conversions.
106
+ * Contains conversion name and optional custom data.
107
+ */
108
+ export type DotCMSConversionPayload = {
109
+ /** Name of the conversion event */
110
+ name: string;
111
+ /** Optional custom user data (any valid JSON) */
112
+ custom?: JsonObject;
98
113
  };
99
114
  /**
100
115
  * Complete data structure for content impression events after enrichment.
@@ -112,6 +127,21 @@ export type DotCMSContentClickEventData = DotCMSContentClickPayload & {
112
127
  /** Minimal page data where the click occurred (added by enricher) */
113
128
  page: DotCMSContentImpressionPageData;
114
129
  };
130
+ /**
131
+ * Complete data structure for conversion events after enrichment.
132
+ * Includes page data added by the enricher plugin.
133
+ */
134
+ export type DotCMSConversionEventData = {
135
+ /** Conversion information */
136
+ conversion: {
137
+ /** Name of the user-defined conversion */
138
+ name: string;
139
+ };
140
+ /** Page data where the conversion occurred (added by enricher) */
141
+ page: DotCMSContentImpressionPageData;
142
+ /** Optional custom user data (any valid JSON) */
143
+ custom?: JsonObject;
144
+ };
115
145
  /**
116
146
  * Pageview event structure.
117
147
  */
@@ -124,6 +154,10 @@ export type DotCMSContentImpressionEvent = DotCMSEventBase<typeof DotCMSPredefin
124
154
  * Content click event structure.
125
155
  */
126
156
  export type DotCMSContentClickEvent = DotCMSEventBase<typeof DotCMSPredefinedEventType.CONTENT_CLICK, DotCMSContentClickEventData>;
157
+ /**
158
+ * Conversion event structure.
159
+ */
160
+ export type DotCMSConversionEvent = DotCMSEventBase<typeof DotCMSPredefinedEventType.CONVERSION, DotCMSConversionEventData>;
127
161
  /**
128
162
  * Custom event structure.
129
163
  */
@@ -132,4 +166,4 @@ export type DotCMSCustomEvent = DotCMSEventBase<DotCMSCustomEventType, DotCMSCus
132
166
  * Union type for all possible analytics events.
133
167
  * Used primarily for type documentation and validation.
134
168
  */
135
- export type DotCMSEvent = DotCMSPageViewEvent | DotCMSContentImpressionEvent | DotCMSContentClickEvent | DotCMSCustomEvent;
169
+ export type DotCMSEvent = DotCMSPageViewEvent | DotCMSContentImpressionEvent | DotCMSContentClickEvent | DotCMSConversionEvent | DotCMSCustomEvent;
@@ -45,20 +45,29 @@ export interface ViewportMetrics {
45
45
  }
46
46
  /**
47
47
  * Main interface for the DotCMS Analytics SDK.
48
- * Provides the core methods for tracking page views and custom events.
48
+ * Provides the core methods for tracking page views, custom events, and conversions.
49
49
  */
50
50
  export interface DotCMSAnalytics {
51
51
  /**
52
52
  * Track a page view event.
53
53
  * @param payload - Optional custom data to include with the page view (any valid JSON object)
54
54
  */
55
- pageView: (payload?: JsonObject) => void;
55
+ pageView(): void;
56
+ pageView(payload: JsonObject): void;
56
57
  /**
57
58
  * Track a custom event.
58
59
  * @param eventName - The name/type of the event to track
59
60
  * @param payload - Custom data to include with the event (any valid JSON object)
60
61
  */
61
- track: (eventName: string, payload: JsonObject) => void;
62
+ track(eventName: string): void;
63
+ track(eventName: string, payload: JsonObject): void;
64
+ /**
65
+ * Track a conversion event.
66
+ * @param name - Name of the conversion (e.g., 'purchase', 'download', 'signup')
67
+ * @param options - Optional custom data and element information
68
+ */
69
+ conversion(name: string): void;
70
+ conversion(name: string, options: JsonObject): void;
62
71
  }
63
72
  /**
64
73
  * Configuration interface for DotCMS Analytics SDK.
@@ -1,27 +1,33 @@
1
- import { useMemo as n, useCallback as o } from "react";
2
- import { getUVEState as u } from "../../../uve/src/lib/core/core.utils.js";
1
+ import { useMemo as s, useCallback as o } from "react";
2
+ import { getUVEState as l } from "../../../uve/src/lib/core/core.utils.js";
3
3
  import "../../../uve/src/internal/constants.js";
4
- import { initializeAnalytics as l } from "../internal/utils.js";
5
- const h = (r) => {
6
- const t = n(() => l(r), [r.server, r.siteAuth]), e = n(() => !!u(), []);
4
+ import { initializeAnalytics as m } from "../internal/utils.js";
5
+ const h = (i) => {
6
+ const t = s(() => m(i), [i.server, i.siteAuth]), e = s(() => !!l(), []);
7
7
  if (!t)
8
8
  throw new Error(
9
9
  "DotCMS Analytics: Failed to initialize. Please verify the required configuration (server and siteAuth)."
10
10
  );
11
11
  const a = o(
12
- (i, c = {}) => {
13
- e || t.track(i, c);
12
+ (r, n = {}) => {
13
+ e || t.track(r, n);
14
14
  },
15
15
  [t, e]
16
- ), s = o(
17
- (i = {}) => {
18
- e || t.pageView(i);
16
+ ), c = o(
17
+ (r = {}) => {
18
+ e || t.pageView(r);
19
+ },
20
+ [t, e]
21
+ ), u = o(
22
+ (r, n = {}) => {
23
+ e || t.conversion(r, n);
19
24
  },
20
25
  [t, e]
21
26
  );
22
27
  return {
23
28
  track: a,
24
- pageView: s
29
+ pageView: c,
30
+ conversion: u
25
31
  };
26
32
  };
27
33
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/analytics",
3
- "version": "1.2.0-next.10",
3
+ "version": "1.2.0-next.11",
4
4
  "description": "Official JavaScript library for Content Analytics with DotCMS.",
5
5
  "repository": {
6
6
  "type": "git",