@dotcms/analytics 1.2.3 → 1.2.4-next.2

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.
@@ -1,6 +1,6 @@
1
- import { ANALYTICS_JS_DEFAULT_PROPERTIES as _, SESSION_STORAGE_KEY as g, DEFAULT_SESSION_TIMEOUT_MINUTES as p, USER_ID_KEY as m, DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS as T, EXPECTED_UTM_KEYS as D, CONTENTLET_CLASS as h } from "../constants/dot-analytics.constants.js";
2
- import { DotLogger as E } from "../dot-analytics.logger.js";
3
- function $(t) {
1
+ import { ANALYTICS_JS_DEFAULT_PROPERTIES as p, SESSION_STORAGE_KEY as g, DEFAULT_SESSION_TIMEOUT_MINUTES as T, USER_ID_KEY as f, DEFAULT_IMPRESSION_MUTATION_OBSERVER_DEBOUNCE_MS as I, EXPECTED_UTM_KEYS as D, CONTENTLET_CLASS as h } from "../constants/dot-analytics.constants.js";
2
+ import { DotLogger as y } from "../dot-analytics.logger.js";
3
+ function P(t) {
4
4
  const e = [];
5
5
  return t.siteAuth?.trim() || e.push('"siteAuth"'), t.server?.trim() || e.push('"server"'), e.length > 0 ? e : null;
6
6
  }
@@ -8,7 +8,7 @@ let d = null, u = null;
8
8
  const l = (t) => {
9
9
  const e = Date.now(), n = Math.random().toString(36).substr(2, 9), s = Math.random().toString(36).substr(2, 9);
10
10
  return `${t}_${e}_${n}${s}`;
11
- }, f = {
11
+ }, w = {
12
12
  getItem: (t) => {
13
13
  try {
14
14
  return localStorage.getItem(t);
@@ -19,20 +19,49 @@ const l = (t) => {
19
19
  setItem: (t, e) => {
20
20
  try {
21
21
  localStorage.setItem(t, e);
22
+ } catch (n) {
23
+ throw console.warn(`DotCMS Analytics [Core]: Could not save ${t} to localStorage`), n;
24
+ }
25
+ }
26
+ }, R = {
27
+ getItem: (t) => {
28
+ try {
29
+ return sessionStorage.getItem(t);
30
+ } catch {
31
+ return null;
32
+ }
33
+ },
34
+ setItem: (t, e) => {
35
+ try {
36
+ sessionStorage.setItem(t, e);
37
+ } catch (n) {
38
+ throw console.warn(`DotCMS Analytics [Core]: Could not save ${t} to sessionStorage`), n;
39
+ }
40
+ },
41
+ removeItem: (t) => {
42
+ try {
43
+ sessionStorage.removeItem(t);
22
44
  } catch {
23
- console.warn(`DotCMS Analytics [Core]: Could not save ${t} to localStorage`);
45
+ console.warn(`DotCMS Analytics [Core]: Could not remove ${t} from sessionStorage`);
24
46
  }
25
47
  }
26
- }, I = () => {
27
- let t = f.getItem(m);
28
- return t || (t = l("user"), f.setItem(m, t)), t;
29
- }, y = (t) => {
48
+ }, E = () => {
49
+ let t = w.getItem(f);
50
+ if (!t) {
51
+ t = l("user");
52
+ try {
53
+ w.setItem(f, t);
54
+ } catch {
55
+ }
56
+ }
57
+ return t;
58
+ }, C = (t) => {
30
59
  const e = new Date(t), n = /* @__PURE__ */ new Date(), s = new Date(
31
60
  e.getUTCFullYear(),
32
61
  e.getUTCMonth(),
33
62
  e.getUTCDate()
34
- ), r = new Date(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate());
35
- return s.getTime() !== r.getTime();
63
+ ), o = new Date(n.getUTCFullYear(), n.getUTCMonth(), n.getUTCDate());
64
+ return s.getTime() !== o.getTime();
36
65
  }, v = () => {
37
66
  const t = Date.now();
38
67
  if (typeof window > "u")
@@ -40,16 +69,16 @@ const l = (t) => {
40
69
  try {
41
70
  const e = sessionStorage.getItem(g);
42
71
  if (e) {
43
- const { sessionId: r, startTime: o, lastActivity: a } = JSON.parse(e), i = !y(o), c = t - a < p * 60 * 1e3;
44
- if (i && c)
72
+ const { sessionId: o, startTime: r, lastActivity: c } = JSON.parse(e), a = !C(r), i = t - c < T * 60 * 1e3;
73
+ if (a && i)
45
74
  return sessionStorage.setItem(
46
75
  g,
47
76
  JSON.stringify({
48
- sessionId: r,
49
- startTime: o,
77
+ sessionId: o,
78
+ startTime: r,
50
79
  lastActivity: t
51
80
  })
52
- ), r;
81
+ ), o;
53
82
  }
54
83
  const n = l("session"), s = {
55
84
  sessionId: n,
@@ -60,58 +89,58 @@ const l = (t) => {
60
89
  } catch {
61
90
  return l("session_fallback");
62
91
  }
63
- }, P = (t) => {
64
- const e = v(), n = I(), s = C();
92
+ }, x = (t) => {
93
+ const e = v(), n = E(), s = A();
65
94
  return {
66
95
  site_auth: t.siteAuth,
67
96
  session_id: e,
68
97
  user_id: n,
69
98
  device: s
70
99
  };
71
- }, w = () => d || (d = {
100
+ }, _ = () => d || (d = {
72
101
  user_language: navigator.language,
73
102
  doc_encoding: document.characterSet || document.charset,
74
103
  screen_resolution: typeof screen < "u" && screen.width && screen.height ? `${screen.width}x${screen.height}` : ""
75
- }, d), C = () => {
76
- const t = w(), e = window.innerWidth || document.documentElement.clientWidth || 0, n = window.innerHeight || document.documentElement.clientHeight || 0;
104
+ }, d), A = () => {
105
+ const t = _(), e = window.innerWidth || document.documentElement.clientWidth || 0, n = window.innerHeight || document.documentElement.clientHeight || 0;
77
106
  return {
78
107
  screen_resolution: t.screen_resolution ?? "",
79
108
  language: t.user_language ?? "",
80
109
  viewport_width: String(e),
81
110
  viewport_height: String(n)
82
111
  };
83
- }, A = (t) => {
112
+ }, b = (t) => {
84
113
  const e = t.search;
85
114
  if (u && u.search === e)
86
115
  return u.params;
87
116
  const n = new URLSearchParams(e), s = {};
88
- return D.forEach((r) => {
89
- const o = n.get(r);
90
- if (o) {
91
- const a = r.replace("utm_", "");
92
- s[a] = o;
117
+ return D.forEach((o) => {
118
+ const r = n.get(o);
119
+ if (r) {
120
+ const c = o.replace("utm_", "");
121
+ s[c] = r;
93
122
  }
94
123
  }), u = { search: e, params: s }, s;
95
124
  }, O = () => {
96
125
  try {
97
- const t = (/* @__PURE__ */ new Date()).getTimezoneOffset(), e = t > 0 ? "-" : "+", n = Math.abs(t), s = Math.floor(n / 60), r = n % 60;
98
- return `${e}${s.toString().padStart(2, "0")}:${r.toString().padStart(2, "0")}`;
126
+ const t = (/* @__PURE__ */ new Date()).getTimezoneOffset(), e = t > 0 ? "-" : "+", n = Math.abs(t), s = Math.floor(n / 60), o = n % 60;
127
+ return `${e}${s.toString().padStart(2, "0")}:${o.toString().padStart(2, "0")}`;
99
128
  } catch {
100
129
  return "+00:00";
101
130
  }
102
- }, N = () => {
131
+ }, M = () => {
103
132
  try {
104
- const t = /* @__PURE__ */ new Date(), e = O(), n = t.getFullYear(), s = (t.getMonth() + 1).toString().padStart(2, "0"), r = t.getDate().toString().padStart(2, "0"), o = t.getHours().toString().padStart(2, "0"), a = t.getMinutes().toString().padStart(2, "0"), i = t.getSeconds().toString().padStart(2, "0");
105
- return `${n}-${s}-${r}T${o}:${a}:${i}${e}`;
133
+ const t = /* @__PURE__ */ new Date(), e = O(), n = t.getFullYear(), s = (t.getMonth() + 1).toString().padStart(2, "0"), o = t.getDate().toString().padStart(2, "0"), r = t.getHours().toString().padStart(2, "0"), c = t.getMinutes().toString().padStart(2, "0"), a = t.getSeconds().toString().padStart(2, "0");
134
+ return `${n}-${s}-${o}T${r}:${c}:${a}${e}`;
106
135
  } catch {
107
136
  return (/* @__PURE__ */ new Date()).toISOString();
108
137
  }
109
- }, R = (t, e = typeof window < "u" ? window.location : {}) => {
110
- const n = N(), s = w(), { properties: r } = t, o = {};
111
- Object.keys(r).forEach((c) => {
112
- _.includes(c) || (o[c] = r[c]);
138
+ }, Y = (t, e = typeof window < "u" ? window.location : {}) => {
139
+ const n = M(), s = _(), { properties: o } = t, r = {};
140
+ Object.keys(o).forEach((i) => {
141
+ p.includes(i) || (r[i] = o[i]);
113
142
  });
114
- const a = {
143
+ const c = {
115
144
  url: e.href,
116
145
  doc_encoding: s.doc_encoding,
117
146
  doc_hash: e.hash,
@@ -119,28 +148,28 @@ const l = (t) => {
119
148
  doc_search: e.search,
120
149
  doc_host: e.hostname,
121
150
  doc_path: e.pathname,
122
- title: r.title ?? document?.title
123
- }, i = A(e);
151
+ title: o.title ?? document?.title
152
+ }, a = b(e);
124
153
  return {
125
154
  ...t,
126
- page: a,
127
- ...Object.keys(i).length > 0 && { utm: i },
155
+ page: c,
156
+ ...Object.keys(a).length > 0 && { utm: a },
128
157
  // Only include custom if there are user-provided properties
129
- ...Object.keys(o).length > 0 && { custom: o },
158
+ ...Object.keys(r).length > 0 && { custom: r },
130
159
  local_time: n
131
160
  };
132
161
  };
133
- function b(t, e) {
162
+ function L(t, e) {
134
163
  let n = 0;
135
164
  return (...s) => {
136
- const r = Date.now();
137
- r - n >= e && (t(...s), n = r);
165
+ const o = Date.now();
166
+ o - n >= e && (t(...s), n = o);
138
167
  };
139
168
  }
140
- function x(t) {
169
+ function B(t) {
141
170
  return t.dataset.dotIdentifier || null;
142
171
  }
143
- function Y(t) {
172
+ function F(t) {
144
173
  return {
145
174
  identifier: t.dataset.dotIdentifier || "",
146
175
  inode: t.dataset.dotInode || "",
@@ -149,51 +178,59 @@ function Y(t) {
149
178
  baseType: t.dataset.dotBasetype || ""
150
179
  };
151
180
  }
152
- const B = 100, M = () => typeof window < "u" && typeof document < "u", F = () => Array.from(document.querySelectorAll(`.${h}`)), k = (t, e = T) => {
153
- const n = b(t, e), s = new MutationObserver((r) => {
181
+ const z = 100, N = () => typeof window < "u" && typeof document < "u", H = () => Array.from(document.querySelectorAll(`.${h}`)), J = (t, e = I) => {
182
+ const n = L(t, e), s = new MutationObserver((r) => {
154
183
  r.some((a) => a.addedNodes.length === 0 && a.removedNodes.length === 0 ? !1 : [
155
184
  ...Array.from(a.addedNodes),
156
185
  ...Array.from(a.removedNodes)
157
- ].some((c) => {
158
- if (c.nodeType !== Node.ELEMENT_NODE)
186
+ ].some((m) => {
187
+ if (m.nodeType !== Node.ELEMENT_NODE)
159
188
  return !1;
160
- const S = c;
189
+ const S = m;
161
190
  return S.classList?.contains(h) ? !0 : S.querySelector?.(`.${h}`) !== null;
162
191
  })) && n();
163
- });
164
- return s.observe(document.body, {
192
+ }), o = document.body || document.documentElement;
193
+ return o ? s.observe(o, {
165
194
  childList: !0,
166
195
  subtree: !0,
167
196
  attributes: !1,
168
197
  characterData: !1
198
+ }) : window.addEventListener("DOMContentLoaded", () => {
199
+ document.body && s.observe(document.body, {
200
+ childList: !0,
201
+ subtree: !0,
202
+ attributes: !1,
203
+ characterData: !1
204
+ });
169
205
  }), s;
170
- }, z = (t) => {
171
- M() && (window.addEventListener("beforeunload", t), window.addEventListener("pagehide", t));
172
- }, H = (t, e) => {
206
+ }, K = (t) => {
207
+ N() && (window.addEventListener("beforeunload", t), window.addEventListener("pagehide", t));
208
+ }, j = (t, e) => {
173
209
  const n = e.logLevel ?? (e.debug ? "debug" : "warn");
174
- return new E("Analytics", t, n);
175
- }, J = (t, e, n) => [
210
+ return new y("Analytics", t, n);
211
+ }, W = (t, e, n) => [
176
212
  t.impressions && e(t),
177
213
  t.clicks && n(t)
178
214
  ].filter(Boolean);
179
215
  export {
180
- B as INITIAL_SCAN_DELAY_MS,
181
- k as createContentletObserver,
182
- H as createPluginLogger,
183
- b as createThrottle,
184
- R as enrichPagePayloadOptimized,
185
- Y as extractContentletData,
186
- x as extractContentletIdentifier,
187
- A as extractUTMParameters,
188
- F as findContentlets,
216
+ z as INITIAL_SCAN_DELAY_MS,
217
+ J as createContentletObserver,
218
+ j as createPluginLogger,
219
+ L as createThrottle,
220
+ Y as enrichPagePayloadOptimized,
221
+ F as extractContentletData,
222
+ B as extractContentletIdentifier,
223
+ b as extractUTMParameters,
224
+ H as findContentlets,
189
225
  l as generateSecureId,
190
- P as getAnalyticsContext,
191
- C as getDeviceDataForContext,
192
- J as getEnhancedTrackingPlugins,
193
- N as getLocalTime,
226
+ x as getAnalyticsContext,
227
+ A as getDeviceDataForContext,
228
+ W as getEnhancedTrackingPlugins,
229
+ M as getLocalTime,
194
230
  v as getSessionId,
195
- I as getUserId,
196
- M as isBrowser,
197
- z as setupPluginCleanup,
198
- $ as validateAnalyticsConfig
231
+ E as getUserId,
232
+ N as isBrowser,
233
+ R as safeSessionStorage,
234
+ K as setupPluginCleanup,
235
+ P as validateAnalyticsConfig
199
236
  };
@@ -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 `pageView()` methods for analytics tracking
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 s, useCallback as o } from "react";
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 m } from "../internal/utils.js";
5
- const h = (i) => {
6
- const t = s(() => m(i), [i.server, i.siteAuth]), e = s(() => !!l(), []);
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
- throw new Error(
9
- "DotCMS Analytics: Failed to initialize. Please verify the required configuration (server and siteAuth)."
10
- );
11
- const a = o(
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, e]
16
- ), c = o(
17
- (r = {}) => {
18
- e || t.pageView(r);
27
+ [t]
28
+ ), s = r(
29
+ (e = {}) => {
30
+ t.pageView(e);
19
31
  },
20
- [t, e]
21
- ), u = o(
22
- (r, n = {}) => {
23
- e || t.conversion(r, n);
32
+ [t]
33
+ ), a = r(
34
+ (e, n = {}) => {
35
+ t.conversion(e, n);
24
36
  },
25
- [t, e]
37
+ [t]
26
38
  );
27
39
  return {
28
- track: a,
29
- pageView: c,
30
- conversion: u
40
+ track: o,
41
+ pageView: s,
42
+ conversion: a
31
43
  };
32
44
  };
33
45
  export {
34
- h as useContentAnalytics
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
- * - Disabled inside UVE editor.
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 s, useSearchParams as u } from "next/navigation";
2
- import { useRef as c, useEffect as a } from "react";
3
- import { getUVEState as m } from "../../../uve/src/lib/core/core.utils.js";
4
- import "../../../uve/src/internal/constants.js";
5
- const p = (t, e) => `${t}${e?.toString() ? "?" + e.toString() : ""}`;
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 (!t) return;
10
- const i = (f) => {
11
- m() || f !== r.current && (r.current = f, t.pageView());
7
+ if (!e) return;
8
+ const c = (s) => {
9
+ s !== r.current && (r.current = s, e.pageView());
12
10
  };
13
- e && console.info("DotCMS Analytics [React]: using Next.js App Router tracking"), i(p(o, n));
14
- }, [t, o, n, e]);
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
- l as useRouterTracker
15
+ R as useRouterTracker
18
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/analytics",
3
- "version": "1.2.3",
3
+ "version": "1.2.4-next.2",
4
4
  "description": "Official JavaScript library for Content Analytics with DotCMS.",
5
5
  "repository": {
6
6
  "type": "git",