@dotcms/analytics 1.2.4-next.1 → 1.2.4-next.3
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 +495 -535
- package/lib/core/dot-analytics.content.js +25 -21
- package/lib/core/plugin/impression/dot-analytics.impression-tracker.js +13 -21
- package/lib/react/hook/useContentAnalytics.d.ts +1 -2
- package/lib/react/hook/useContentAnalytics.js +35 -23
- package/lib/react/hook/useRouterTracker.d.ts +1 -1
- package/lib/react/hook/useRouterTracker.js +11 -13
- package/package.json +1 -1
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { Analytics as l } from "analytics";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { getUVEState as d } from "../../uve/src/lib/core/core.utils.js";
|
|
3
|
+
import "../../uve/src/internal/constants.js";
|
|
4
|
+
import { dotAnalyticsClickPlugin as y } from "./plugin/click/dot-analytics.click.plugin.js";
|
|
5
|
+
import { dotAnalyticsEnricherPlugin as m } from "./plugin/enricher/dot-analytics.enricher.plugin.js";
|
|
4
6
|
import { dotAnalyticsIdentityPlugin as u } from "./plugin/identity/dot-analytics.identity.plugin.js";
|
|
5
|
-
import { dotAnalyticsImpressionPlugin as
|
|
6
|
-
import { dotAnalytics as
|
|
7
|
-
import { ANALYTICS_WINDOWS_ACTIVE_KEY as
|
|
8
|
-
import { validateAnalyticsConfig as C, getEnhancedTrackingPlugins as
|
|
9
|
-
import { cleanupActivityTracking as
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
7
|
+
import { dotAnalyticsImpressionPlugin as A } from "./plugin/impression/dot-analytics.impression.plugin.js";
|
|
8
|
+
import { dotAnalytics as p } from "./plugin/main/dot-analytics.plugin.js";
|
|
9
|
+
import { ANALYTICS_WINDOWS_ACTIVE_KEY as e, ANALYTICS_WINDOWS_CLEANUP_KEY as f, DotCMSPredefinedEventType as w } from "./shared/constants/dot-analytics.constants.js";
|
|
10
|
+
import { validateAnalyticsConfig as C, isBrowser as g, getEnhancedTrackingPlugins as E } from "./shared/utils/dot-analytics.utils.js";
|
|
11
|
+
import { cleanupActivityTracking as S } from "./plugin/identity/dot-analytics.identity.activity-tracker.js";
|
|
12
|
+
const O = (t) => {
|
|
13
|
+
const r = C(t);
|
|
14
|
+
if (r)
|
|
13
15
|
return console.error(
|
|
14
|
-
`DotCMS Analytics [Core]: Missing ${
|
|
15
|
-
), typeof window < "u" && (window[
|
|
16
|
-
|
|
16
|
+
`DotCMS Analytics [Core]: Missing ${r.join(" and ")} in configuration`
|
|
17
|
+
), typeof window < "u" && (window[e] = !1), null;
|
|
18
|
+
if (g() && d())
|
|
19
|
+
return console.warn("DotCMS Analytics [Core]: Analytics disabled inside UVE editor"), window[e] = !1, null;
|
|
20
|
+
const s = E(
|
|
17
21
|
t,
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
A,
|
|
23
|
+
y
|
|
20
24
|
), i = l({
|
|
21
25
|
app: "dotAnalytics",
|
|
22
26
|
debug: t.debug,
|
|
@@ -25,13 +29,13 @@ const T = (t) => {
|
|
|
25
29
|
// Inject identity context
|
|
26
30
|
...s,
|
|
27
31
|
//Track content impressions & clicks (conditionally loaded)
|
|
28
|
-
|
|
32
|
+
m(),
|
|
29
33
|
// Enrich and clean payload with page, device, utm data and custom data
|
|
30
|
-
|
|
34
|
+
p(t)
|
|
31
35
|
// Send events to server
|
|
32
36
|
]
|
|
33
|
-
}),
|
|
34
|
-
return typeof window < "u" && (window.addEventListener("beforeunload",
|
|
37
|
+
}), a = () => S();
|
|
38
|
+
return typeof window < "u" && (window.addEventListener("beforeunload", a), window[f] = a, window[e] = !0, window.dispatchEvent(new CustomEvent("dotcms:analytics:ready"))), {
|
|
35
39
|
/**
|
|
36
40
|
* Track a page view.
|
|
37
41
|
* Session activity is automatically updated by the identity plugin.
|
|
@@ -74,10 +78,10 @@ const T = (t) => {
|
|
|
74
78
|
name: n,
|
|
75
79
|
...Object.keys(o).length > 0 && { custom: o }
|
|
76
80
|
};
|
|
77
|
-
i.track(
|
|
81
|
+
i.track(w.CONVERSION, c);
|
|
78
82
|
}
|
|
79
83
|
};
|
|
80
84
|
};
|
|
81
85
|
export {
|
|
82
|
-
|
|
86
|
+
O as initializeContentAnalytics
|
|
83
87
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "
|
|
3
|
-
import {
|
|
4
|
-
|
|
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 {
|
|
1
|
+
import { getViewportMetrics as m, isElementMeetingVisibilityThreshold as d } from "./dot-analytics.impression.utils.js";
|
|
2
|
+
import { DEFAULT_IMPRESSION_CONFIG as l, IMPRESSION_EVENT_TYPE as u } from "../../shared/constants/dot-analytics.constants.js";
|
|
3
|
+
import { createPluginLogger as g, isBrowser as a, INITIAL_SCAN_DELAY_MS as p, findContentlets as b, extractContentletIdentifier as c, createContentletObserver as f, extractContentletData as v } from "../../shared/utils/dot-analytics.utils.js";
|
|
4
|
+
class T {
|
|
7
5
|
constructor(e) {
|
|
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 =
|
|
6
|
+
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 = g("Impression", e), this.impressionConfig = this.resolveImpressionConfig(e.impressions);
|
|
9
7
|
}
|
|
10
8
|
/**
|
|
11
9
|
* Subscribe to impression events
|
|
@@ -38,15 +36,9 @@ class E {
|
|
|
38
36
|
}
|
|
39
37
|
/** Initializes tracking: sets up observers, finds contentlets, handles visibility/navigation */
|
|
40
38
|
initialize() {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
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);
|
|
49
|
-
}
|
|
39
|
+
a() && (this.initializeIntersectionObserver(), typeof window < "u" && setTimeout(() => {
|
|
40
|
+
this.logger.debug("Running initial scan after timeout..."), this.findAndObserveContentletElements();
|
|
41
|
+
}, p), this.initializeDynamicContentDetector(), this.initializePageVisibilityHandler(), this.initializePageNavigationHandler(), this.logger.info("Impression tracking initialized with config:", this.impressionConfig));
|
|
50
42
|
}
|
|
51
43
|
/** Sets up IntersectionObserver with configured visibility threshold */
|
|
52
44
|
initializeIntersectionObserver() {
|
|
@@ -92,7 +84,7 @@ class E {
|
|
|
92
84
|
}
|
|
93
85
|
/** Watches for new contentlets added to DOM (debounced for performance) */
|
|
94
86
|
initializeDynamicContentDetector() {
|
|
95
|
-
a() && (this.mutationObserver =
|
|
87
|
+
a() && (this.mutationObserver = f(() => {
|
|
96
88
|
this.findAndObserveContentletElements();
|
|
97
89
|
}), this.logger.info("MutationObserver enabled for dynamic content detection"));
|
|
98
90
|
}
|
|
@@ -150,7 +142,7 @@ class E {
|
|
|
150
142
|
trackAndSendImpression(e, i) {
|
|
151
143
|
const t = this.elementImpressionStates.get(e);
|
|
152
144
|
if (!t) return;
|
|
153
|
-
const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n =
|
|
145
|
+
const s = t.visibleSince ? Date.now() - t.visibleSince : 0, n = v(i), r = m(i), o = parseInt(i.dataset.dotDomIndex || "-1", 10), h = {
|
|
154
146
|
content: {
|
|
155
147
|
identifier: n.identifier,
|
|
156
148
|
inode: n.inode,
|
|
@@ -162,7 +154,7 @@ class E {
|
|
|
162
154
|
dom_index: o
|
|
163
155
|
}
|
|
164
156
|
};
|
|
165
|
-
this.notifySubscribers(
|
|
157
|
+
this.notifySubscribers(u, h), this.markImpressionAsTracked(e), t.timer = null, t.visibleSince = null, t.tracked = !0, this.observer && this.observer.unobserve(i), this.logger.info(
|
|
166
158
|
`Fired impression for ${e} (dwell: ${s}ms) - element unobserved`,
|
|
167
159
|
n
|
|
168
160
|
);
|
|
@@ -177,7 +169,7 @@ class E {
|
|
|
177
169
|
}
|
|
178
170
|
/** Post-dwell check: verifies element still meets visibility threshold */
|
|
179
171
|
isElementStillVisible(e) {
|
|
180
|
-
return document.visibilityState !== "visible" ? !1 :
|
|
172
|
+
return document.visibilityState !== "visible" ? !1 : d(
|
|
181
173
|
e,
|
|
182
174
|
this.impressionConfig.visibilityThreshold
|
|
183
175
|
);
|
|
@@ -198,5 +190,5 @@ class E {
|
|
|
198
190
|
}
|
|
199
191
|
}
|
|
200
192
|
export {
|
|
201
|
-
|
|
193
|
+
T as DotCMSImpressionTracker
|
|
202
194
|
};
|
|
@@ -51,7 +51,6 @@ import { DotCMSAnalytics, DotCMSAnalyticsConfig } from '../../core/shared/models
|
|
|
51
51
|
* @param config.server - The URL of your DotCMS Analytics server
|
|
52
52
|
* @param config.siteKey - Your unique site key for authentication
|
|
53
53
|
* @param config.debug - Optional. Set to true to see analytics events in the console
|
|
54
|
-
* @returns Object with `track()` and `
|
|
55
|
-
* @throws {Error} If the configuration is invalid (missing server or siteKey)
|
|
54
|
+
* @returns Object with `track()`, `pageView()`, and `conversion()` methods for analytics tracking
|
|
56
55
|
*/
|
|
57
56
|
export declare const useContentAnalytics: (config: DotCMSAnalyticsConfig) => DotCMSAnalytics;
|
|
@@ -1,35 +1,47 @@
|
|
|
1
|
-
import { useMemo as
|
|
1
|
+
import { useMemo as c, useCallback as r } from "react";
|
|
2
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
|
|
5
|
-
const
|
|
6
|
-
|
|
4
|
+
import { initializeAnalytics as u } from "../internal/utils.js";
|
|
5
|
+
const A = {
|
|
6
|
+
track: () => {
|
|
7
|
+
},
|
|
8
|
+
pageView: () => {
|
|
9
|
+
},
|
|
10
|
+
conversion: () => {
|
|
11
|
+
}
|
|
12
|
+
}, v = (i) => {
|
|
13
|
+
const t = c(() => {
|
|
14
|
+
const e = u(i);
|
|
15
|
+
return e || (l() ? console.warn(
|
|
16
|
+
"DotCMS Analytics [React]: Analytics is not initialized because the site is inside the UVE editor. All tracking calls will be ignored."
|
|
17
|
+
) : console.error(
|
|
18
|
+
"DotCMS Analytics [React]: Failed to initialize. Please verify the required configuration (server and siteAuth)."
|
|
19
|
+
)), e;
|
|
20
|
+
}, [i.server, i.siteAuth]);
|
|
7
21
|
if (!t)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
(r, n = {}) => {
|
|
13
|
-
e || t.track(r, n);
|
|
22
|
+
return A;
|
|
23
|
+
const o = r(
|
|
24
|
+
(e, n = {}) => {
|
|
25
|
+
t.track(e, n);
|
|
14
26
|
},
|
|
15
|
-
[t
|
|
16
|
-
),
|
|
17
|
-
(
|
|
18
|
-
|
|
27
|
+
[t]
|
|
28
|
+
), s = r(
|
|
29
|
+
(e = {}) => {
|
|
30
|
+
t.pageView(e);
|
|
19
31
|
},
|
|
20
|
-
[t
|
|
21
|
-
),
|
|
22
|
-
(
|
|
23
|
-
|
|
32
|
+
[t]
|
|
33
|
+
), a = r(
|
|
34
|
+
(e, n = {}) => {
|
|
35
|
+
t.conversion(e, n);
|
|
24
36
|
},
|
|
25
|
-
[t
|
|
37
|
+
[t]
|
|
26
38
|
);
|
|
27
39
|
return {
|
|
28
|
-
track:
|
|
29
|
-
pageView:
|
|
30
|
-
conversion:
|
|
40
|
+
track: o,
|
|
41
|
+
pageView: s,
|
|
42
|
+
conversion: a
|
|
31
43
|
};
|
|
32
44
|
};
|
|
33
45
|
export {
|
|
34
|
-
|
|
46
|
+
v as useContentAnalytics
|
|
35
47
|
};
|
|
@@ -2,7 +2,7 @@ import { DotCMSAnalytics } from '../../core/shared/models';
|
|
|
2
2
|
/**
|
|
3
3
|
* Tracks page views on route changes using Next.js App Router signals.
|
|
4
4
|
* - Fires a single pageView per unique path+search.
|
|
5
|
-
* -
|
|
5
|
+
* - Automatically disabled inside UVE editor (analytics instance is null).
|
|
6
6
|
* - Requires Next.js App Router; no SPA fallback.
|
|
7
7
|
*
|
|
8
8
|
* @param analytics Analytics singleton instance; if null, does nothing
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import { usePathname as
|
|
2
|
-
import { useRef as
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
function l(t, e = !1) {
|
|
7
|
-
const r = c(null), o = s(), n = u();
|
|
1
|
+
import { usePathname as f, useSearchParams as u } from "next/navigation";
|
|
2
|
+
import { useRef as i, useEffect as a } from "react";
|
|
3
|
+
const m = (e, t) => `${e}${t?.toString() ? "?" + t.toString() : ""}`;
|
|
4
|
+
function R(e, t = !1) {
|
|
5
|
+
const r = i(null), n = f(), o = u();
|
|
8
6
|
a(() => {
|
|
9
|
-
if (!
|
|
10
|
-
const
|
|
11
|
-
|
|
7
|
+
if (!e) return;
|
|
8
|
+
const c = (s) => {
|
|
9
|
+
s !== r.current && (r.current = s, e.pageView());
|
|
12
10
|
};
|
|
13
|
-
|
|
14
|
-
}, [
|
|
11
|
+
t && console.info("DotCMS Analytics [React]: using Next.js App Router tracking"), c(m(n, o));
|
|
12
|
+
}, [e, n, o, t]);
|
|
15
13
|
}
|
|
16
14
|
export {
|
|
17
|
-
|
|
15
|
+
R as useRouterTracker
|
|
18
16
|
};
|