ninetwo-user-tracking 1.0.13 → 1.0.15
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/dist/index.js +160 -95
- package/dist/index.mjs +156 -91
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,38 +27,72 @@ __export(src_exports, {
|
|
|
27
27
|
module.exports = __toCommonJS(src_exports);
|
|
28
28
|
|
|
29
29
|
// src/TrackingProvider.tsx
|
|
30
|
-
var
|
|
30
|
+
var import_react4 = require("react");
|
|
31
31
|
|
|
32
32
|
// src/hooks/useAutoTrackClick.ts
|
|
33
33
|
var import_react = require("react");
|
|
34
34
|
|
|
35
35
|
// src/utils/gtm.ts
|
|
36
|
-
var
|
|
36
|
+
var ATTRIBUTION_KEYS = [
|
|
37
|
+
"utm_source",
|
|
38
|
+
"utm_medium",
|
|
39
|
+
"utm_campaign",
|
|
40
|
+
"utm_term",
|
|
41
|
+
"utm_content",
|
|
42
|
+
"gclid",
|
|
43
|
+
// Google Ads ID
|
|
44
|
+
"fbclid",
|
|
45
|
+
// Facebook Click ID
|
|
46
|
+
"ttclid"
|
|
47
|
+
// TikTok Click ID
|
|
48
|
+
];
|
|
49
|
+
var captureAttribution = () => {
|
|
37
50
|
if (typeof window === "undefined")
|
|
38
51
|
return;
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} catch (err) {
|
|
54
|
-
console.warn("[NineTwo Tracking] gtag falhou, fallback para dataLayer", err);
|
|
52
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
53
|
+
let hasNewData = false;
|
|
54
|
+
ATTRIBUTION_KEYS.forEach((key) => {
|
|
55
|
+
const value = urlParams.get(key);
|
|
56
|
+
if (value) {
|
|
57
|
+
sessionStorage.setItem(`nt_attr_${key}`, value);
|
|
58
|
+
hasNewData = true;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (!sessionStorage.getItem("nt_attr_utm_source") && document.referrer) {
|
|
62
|
+
const referrerUrl = new URL(document.referrer);
|
|
63
|
+
if (referrerUrl.hostname !== window.location.hostname) {
|
|
64
|
+
sessionStorage.setItem("nt_attr_utm_source", "referral");
|
|
65
|
+
sessionStorage.setItem("nt_attr_utm_medium", referrerUrl.hostname);
|
|
55
66
|
}
|
|
56
67
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
};
|
|
69
|
+
var getPersistedAttribution = () => {
|
|
70
|
+
if (typeof window === "undefined")
|
|
71
|
+
return {};
|
|
72
|
+
const attributionData = {};
|
|
73
|
+
ATTRIBUTION_KEYS.forEach((key) => {
|
|
74
|
+
const val = sessionStorage.getItem(`nt_attr_${key}`);
|
|
75
|
+
if (val)
|
|
76
|
+
attributionData[key] = val;
|
|
61
77
|
});
|
|
78
|
+
return attributionData;
|
|
79
|
+
};
|
|
80
|
+
var pushToDataLayer = (props) => {
|
|
81
|
+
if (typeof window === "undefined")
|
|
82
|
+
return;
|
|
83
|
+
const dataLayer = window.dataLayer || [];
|
|
84
|
+
const payload = {
|
|
85
|
+
...getPersistedAttribution(),
|
|
86
|
+
// <--- A MÁGICA ACONTECE AQUI
|
|
87
|
+
event: props.event,
|
|
88
|
+
event_category: props.category,
|
|
89
|
+
event_label: props.label,
|
|
90
|
+
event_type: props.type,
|
|
91
|
+
interaction_time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
92
|
+
...props
|
|
93
|
+
// Permite sobrescrever se necessário
|
|
94
|
+
};
|
|
95
|
+
dataLayer.push(payload);
|
|
62
96
|
};
|
|
63
97
|
|
|
64
98
|
// src/hooks/useAutoTrackClick.ts
|
|
@@ -123,6 +157,69 @@ var useAutoTrackSubmit = (enabled = true) => {
|
|
|
123
157
|
}, [enabled]);
|
|
124
158
|
};
|
|
125
159
|
|
|
160
|
+
// src/hooks/useAutoTagExternal.ts
|
|
161
|
+
var import_react3 = require("react");
|
|
162
|
+
var EXTERNAL_RULES = [
|
|
163
|
+
{
|
|
164
|
+
// Cenario 1: Botão Flutuante do WhatsApp
|
|
165
|
+
selector: ".rdstation-popup-js-floating-button",
|
|
166
|
+
eventType: "click",
|
|
167
|
+
// Tipo de listener
|
|
168
|
+
data: {
|
|
169
|
+
event: "open_wpp_form",
|
|
170
|
+
category: "contact",
|
|
171
|
+
label: "whatsapp_floating_rd",
|
|
172
|
+
type: "click"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
// Cenario 2: Formulário Injetado (RD Station)
|
|
177
|
+
selector: ".rdstation-popup-js-form-identifier",
|
|
178
|
+
eventType: "submit",
|
|
179
|
+
// Tipo de listener
|
|
180
|
+
data: {
|
|
181
|
+
event: "generate_lead",
|
|
182
|
+
category: "leads",
|
|
183
|
+
label: "rd_station_popup",
|
|
184
|
+
type: "submit"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
];
|
|
188
|
+
var useAutoTagExternal = (enabled = true) => {
|
|
189
|
+
(0, import_react3.useEffect)(() => {
|
|
190
|
+
if (!enabled || typeof document === "undefined")
|
|
191
|
+
return;
|
|
192
|
+
const attachListeners = () => {
|
|
193
|
+
EXTERNAL_RULES.forEach((rule) => {
|
|
194
|
+
const elements = document.querySelectorAll(rule.selector);
|
|
195
|
+
elements.forEach((el) => {
|
|
196
|
+
if (el.getAttribute("data-nt-tracked") === "true")
|
|
197
|
+
return;
|
|
198
|
+
el.setAttribute("data-nt-tracked", "true");
|
|
199
|
+
el.setAttribute("data-nt-ut-event", rule.data.event);
|
|
200
|
+
el.addEventListener(rule.eventType, (e) => {
|
|
201
|
+
pushToDataLayer({
|
|
202
|
+
event: rule.data.event,
|
|
203
|
+
category: rule.data.category,
|
|
204
|
+
label: rule.data.label,
|
|
205
|
+
type: rule.data.type
|
|
206
|
+
});
|
|
207
|
+
}, true);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
attachListeners();
|
|
212
|
+
const observer = new MutationObserver((mutations) => {
|
|
213
|
+
const hasAddedNodes = mutations.some((m) => m.addedNodes.length > 0);
|
|
214
|
+
if (hasAddedNodes) {
|
|
215
|
+
attachListeners();
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
219
|
+
return () => observer.disconnect();
|
|
220
|
+
}, [enabled]);
|
|
221
|
+
};
|
|
222
|
+
|
|
126
223
|
// src/TrackingProvider.tsx
|
|
127
224
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
128
225
|
var TrackingProvider = ({
|
|
@@ -132,86 +229,54 @@ var TrackingProvider = ({
|
|
|
132
229
|
}) => {
|
|
133
230
|
useAutoTrackClick(true);
|
|
134
231
|
useAutoTrackSubmit(true);
|
|
135
|
-
(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
232
|
+
useAutoTagExternal(true);
|
|
233
|
+
(0, import_react4.useEffect)(() => {
|
|
234
|
+
captureAttribution();
|
|
235
|
+
if (debug) {
|
|
236
|
+
const source = typeof sessionStorage !== "undefined" ? sessionStorage.getItem("nt_attr_utm_source") : null;
|
|
237
|
+
if (source) {
|
|
238
|
+
console.log(`[NineTwo Tracking] \u{1F517} Origem capturada: ${source}`);
|
|
139
239
|
}
|
|
140
|
-
return;
|
|
141
240
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
if (
|
|
145
|
-
|
|
241
|
+
}, [debug]);
|
|
242
|
+
(0, import_react4.useEffect)(() => {
|
|
243
|
+
if (typeof window === "undefined")
|
|
244
|
+
return;
|
|
245
|
+
if (!gtmId) {
|
|
246
|
+
if (debug)
|
|
247
|
+
console.warn("[NineTwo Tracking] \u26A0\uFE0F GTM ID n\xE3o fornecido.");
|
|
146
248
|
return;
|
|
147
249
|
}
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (debug) {
|
|
153
|
-
console.log("[NineTwo Tracking] Script j\xE1 carregado:", gtmId);
|
|
154
|
-
}
|
|
250
|
+
const scriptId = "ninetwo-gtm-script";
|
|
251
|
+
if (document.getElementById(scriptId)) {
|
|
252
|
+
if (debug)
|
|
253
|
+
console.log("[NineTwo Tracking] \u2139\uFE0F Script GTM j\xE1 existente. Ignorando reinje\xE7\xE3o.");
|
|
155
254
|
return;
|
|
156
255
|
}
|
|
157
256
|
window.dataLayer = window.dataLayer || [];
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
console.error("[NineTwo Tracking] Erro ao carregar
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const inlineScript = document.createElement("script");
|
|
176
|
-
inlineScript.setAttribute("data-ninetwo-tracking", `${gtmId}-inline`);
|
|
177
|
-
inlineScript.innerHTML = `
|
|
178
|
-
window.dataLayer = window.dataLayer || [];
|
|
179
|
-
function gtag(){dataLayer.push(arguments);}
|
|
180
|
-
gtag('js', new Date());
|
|
181
|
-
gtag('config', '${gtmId}', {
|
|
182
|
-
send_page_view: true
|
|
183
|
-
});
|
|
184
|
-
`;
|
|
185
|
-
document.head.appendChild(inlineScript);
|
|
186
|
-
}
|
|
187
|
-
if (isGTM) {
|
|
188
|
-
if (debug) {
|
|
189
|
-
console.log("[NineTwo Tracking] Inicializando GTM:", gtmId);
|
|
190
|
-
}
|
|
191
|
-
window.dataLayer.push({
|
|
192
|
-
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
193
|
-
event: "gtm.js"
|
|
194
|
-
});
|
|
195
|
-
const gtmScript = document.createElement("script");
|
|
196
|
-
gtmScript.async = true;
|
|
197
|
-
gtmScript.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
198
|
-
gtmScript.setAttribute("data-ninetwo-tracking", gtmId);
|
|
199
|
-
gtmScript.onload = () => {
|
|
200
|
-
if (debug) {
|
|
201
|
-
console.log("[NineTwo Tracking] GTM carregado com sucesso");
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
gtmScript.onerror = () => {
|
|
205
|
-
console.error("[NineTwo Tracking] Erro ao carregar GTM");
|
|
206
|
-
};
|
|
207
|
-
document.head.appendChild(gtmScript);
|
|
208
|
-
}
|
|
257
|
+
window.dataLayer.push({
|
|
258
|
+
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
259
|
+
event: "gtm.js"
|
|
260
|
+
});
|
|
261
|
+
const script = document.createElement("script");
|
|
262
|
+
script.id = scriptId;
|
|
263
|
+
script.async = true;
|
|
264
|
+
script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
265
|
+
script.onload = () => {
|
|
266
|
+
if (debug)
|
|
267
|
+
console.log(`[NineTwo Tracking] \u2705 GTM carregado com sucesso! (${gtmId})`);
|
|
268
|
+
};
|
|
269
|
+
script.onerror = () => {
|
|
270
|
+
if (debug)
|
|
271
|
+
console.error("[NineTwo Tracking] \u274C Erro ao carregar script do GTM. Verifique AdBlockers.");
|
|
272
|
+
};
|
|
273
|
+
document.head.appendChild(script);
|
|
209
274
|
}, [gtmId, debug]);
|
|
210
275
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
|
|
211
276
|
};
|
|
212
277
|
|
|
213
278
|
// src/components/TrackView.tsx
|
|
214
|
-
var
|
|
279
|
+
var import_react5 = require("react");
|
|
215
280
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
216
281
|
var TrackView = ({
|
|
217
282
|
children,
|
|
@@ -222,11 +287,11 @@ var TrackView = ({
|
|
|
222
287
|
readTime = 5e3,
|
|
223
288
|
debug = false
|
|
224
289
|
}) => {
|
|
225
|
-
const ref = (0,
|
|
226
|
-
const timerRef = (0,
|
|
227
|
-
const [hasTriggeredView, setHasTriggeredView] = (0,
|
|
228
|
-
const [hasTriggeredRead, setHasTriggeredRead] = (0,
|
|
229
|
-
(0,
|
|
290
|
+
const ref = (0, import_react5.useRef)(null);
|
|
291
|
+
const timerRef = (0, import_react5.useRef)(null);
|
|
292
|
+
const [hasTriggeredView, setHasTriggeredView] = (0, import_react5.useState)(false);
|
|
293
|
+
const [hasTriggeredRead, setHasTriggeredRead] = (0, import_react5.useState)(false);
|
|
294
|
+
(0, import_react5.useEffect)(() => {
|
|
230
295
|
const rootEl = ref.current;
|
|
231
296
|
if (!rootEl)
|
|
232
297
|
return;
|
package/dist/index.mjs
CHANGED
|
@@ -1,36 +1,70 @@
|
|
|
1
1
|
// src/TrackingProvider.tsx
|
|
2
|
-
import { useEffect as
|
|
2
|
+
import { useEffect as useEffect4 } from "react";
|
|
3
3
|
|
|
4
4
|
// src/hooks/useAutoTrackClick.ts
|
|
5
5
|
import { useEffect } from "react";
|
|
6
6
|
|
|
7
7
|
// src/utils/gtm.ts
|
|
8
|
-
var
|
|
8
|
+
var ATTRIBUTION_KEYS = [
|
|
9
|
+
"utm_source",
|
|
10
|
+
"utm_medium",
|
|
11
|
+
"utm_campaign",
|
|
12
|
+
"utm_term",
|
|
13
|
+
"utm_content",
|
|
14
|
+
"gclid",
|
|
15
|
+
// Google Ads ID
|
|
16
|
+
"fbclid",
|
|
17
|
+
// Facebook Click ID
|
|
18
|
+
"ttclid"
|
|
19
|
+
// TikTok Click ID
|
|
20
|
+
];
|
|
21
|
+
var captureAttribution = () => {
|
|
9
22
|
if (typeof window === "undefined")
|
|
10
23
|
return;
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
} catch (err) {
|
|
26
|
-
console.warn("[NineTwo Tracking] gtag falhou, fallback para dataLayer", err);
|
|
24
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
25
|
+
let hasNewData = false;
|
|
26
|
+
ATTRIBUTION_KEYS.forEach((key) => {
|
|
27
|
+
const value = urlParams.get(key);
|
|
28
|
+
if (value) {
|
|
29
|
+
sessionStorage.setItem(`nt_attr_${key}`, value);
|
|
30
|
+
hasNewData = true;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
if (!sessionStorage.getItem("nt_attr_utm_source") && document.referrer) {
|
|
34
|
+
const referrerUrl = new URL(document.referrer);
|
|
35
|
+
if (referrerUrl.hostname !== window.location.hostname) {
|
|
36
|
+
sessionStorage.setItem("nt_attr_utm_source", "referral");
|
|
37
|
+
sessionStorage.setItem("nt_attr_utm_medium", referrerUrl.hostname);
|
|
27
38
|
}
|
|
28
39
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
};
|
|
41
|
+
var getPersistedAttribution = () => {
|
|
42
|
+
if (typeof window === "undefined")
|
|
43
|
+
return {};
|
|
44
|
+
const attributionData = {};
|
|
45
|
+
ATTRIBUTION_KEYS.forEach((key) => {
|
|
46
|
+
const val = sessionStorage.getItem(`nt_attr_${key}`);
|
|
47
|
+
if (val)
|
|
48
|
+
attributionData[key] = val;
|
|
33
49
|
});
|
|
50
|
+
return attributionData;
|
|
51
|
+
};
|
|
52
|
+
var pushToDataLayer = (props) => {
|
|
53
|
+
if (typeof window === "undefined")
|
|
54
|
+
return;
|
|
55
|
+
const dataLayer = window.dataLayer || [];
|
|
56
|
+
const payload = {
|
|
57
|
+
...getPersistedAttribution(),
|
|
58
|
+
// <--- A MÁGICA ACONTECE AQUI
|
|
59
|
+
event: props.event,
|
|
60
|
+
event_category: props.category,
|
|
61
|
+
event_label: props.label,
|
|
62
|
+
event_type: props.type,
|
|
63
|
+
interaction_time: (/* @__PURE__ */ new Date()).toISOString(),
|
|
64
|
+
...props
|
|
65
|
+
// Permite sobrescrever se necessário
|
|
66
|
+
};
|
|
67
|
+
dataLayer.push(payload);
|
|
34
68
|
};
|
|
35
69
|
|
|
36
70
|
// src/hooks/useAutoTrackClick.ts
|
|
@@ -95,6 +129,69 @@ var useAutoTrackSubmit = (enabled = true) => {
|
|
|
95
129
|
}, [enabled]);
|
|
96
130
|
};
|
|
97
131
|
|
|
132
|
+
// src/hooks/useAutoTagExternal.ts
|
|
133
|
+
import { useEffect as useEffect3 } from "react";
|
|
134
|
+
var EXTERNAL_RULES = [
|
|
135
|
+
{
|
|
136
|
+
// Cenario 1: Botão Flutuante do WhatsApp
|
|
137
|
+
selector: ".rdstation-popup-js-floating-button",
|
|
138
|
+
eventType: "click",
|
|
139
|
+
// Tipo de listener
|
|
140
|
+
data: {
|
|
141
|
+
event: "open_wpp_form",
|
|
142
|
+
category: "contact",
|
|
143
|
+
label: "whatsapp_floating_rd",
|
|
144
|
+
type: "click"
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
// Cenario 2: Formulário Injetado (RD Station)
|
|
149
|
+
selector: ".rdstation-popup-js-form-identifier",
|
|
150
|
+
eventType: "submit",
|
|
151
|
+
// Tipo de listener
|
|
152
|
+
data: {
|
|
153
|
+
event: "generate_lead",
|
|
154
|
+
category: "leads",
|
|
155
|
+
label: "rd_station_popup",
|
|
156
|
+
type: "submit"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
];
|
|
160
|
+
var useAutoTagExternal = (enabled = true) => {
|
|
161
|
+
useEffect3(() => {
|
|
162
|
+
if (!enabled || typeof document === "undefined")
|
|
163
|
+
return;
|
|
164
|
+
const attachListeners = () => {
|
|
165
|
+
EXTERNAL_RULES.forEach((rule) => {
|
|
166
|
+
const elements = document.querySelectorAll(rule.selector);
|
|
167
|
+
elements.forEach((el) => {
|
|
168
|
+
if (el.getAttribute("data-nt-tracked") === "true")
|
|
169
|
+
return;
|
|
170
|
+
el.setAttribute("data-nt-tracked", "true");
|
|
171
|
+
el.setAttribute("data-nt-ut-event", rule.data.event);
|
|
172
|
+
el.addEventListener(rule.eventType, (e) => {
|
|
173
|
+
pushToDataLayer({
|
|
174
|
+
event: rule.data.event,
|
|
175
|
+
category: rule.data.category,
|
|
176
|
+
label: rule.data.label,
|
|
177
|
+
type: rule.data.type
|
|
178
|
+
});
|
|
179
|
+
}, true);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
attachListeners();
|
|
184
|
+
const observer = new MutationObserver((mutations) => {
|
|
185
|
+
const hasAddedNodes = mutations.some((m) => m.addedNodes.length > 0);
|
|
186
|
+
if (hasAddedNodes) {
|
|
187
|
+
attachListeners();
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
191
|
+
return () => observer.disconnect();
|
|
192
|
+
}, [enabled]);
|
|
193
|
+
};
|
|
194
|
+
|
|
98
195
|
// src/TrackingProvider.tsx
|
|
99
196
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
100
197
|
var TrackingProvider = ({
|
|
@@ -104,86 +201,54 @@ var TrackingProvider = ({
|
|
|
104
201
|
}) => {
|
|
105
202
|
useAutoTrackClick(true);
|
|
106
203
|
useAutoTrackSubmit(true);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
204
|
+
useAutoTagExternal(true);
|
|
205
|
+
useEffect4(() => {
|
|
206
|
+
captureAttribution();
|
|
207
|
+
if (debug) {
|
|
208
|
+
const source = typeof sessionStorage !== "undefined" ? sessionStorage.getItem("nt_attr_utm_source") : null;
|
|
209
|
+
if (source) {
|
|
210
|
+
console.log(`[NineTwo Tracking] \u{1F517} Origem capturada: ${source}`);
|
|
111
211
|
}
|
|
112
|
-
return;
|
|
113
212
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (
|
|
117
|
-
|
|
213
|
+
}, [debug]);
|
|
214
|
+
useEffect4(() => {
|
|
215
|
+
if (typeof window === "undefined")
|
|
216
|
+
return;
|
|
217
|
+
if (!gtmId) {
|
|
218
|
+
if (debug)
|
|
219
|
+
console.warn("[NineTwo Tracking] \u26A0\uFE0F GTM ID n\xE3o fornecido.");
|
|
118
220
|
return;
|
|
119
221
|
}
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (debug) {
|
|
125
|
-
console.log("[NineTwo Tracking] Script j\xE1 carregado:", gtmId);
|
|
126
|
-
}
|
|
222
|
+
const scriptId = "ninetwo-gtm-script";
|
|
223
|
+
if (document.getElementById(scriptId)) {
|
|
224
|
+
if (debug)
|
|
225
|
+
console.log("[NineTwo Tracking] \u2139\uFE0F Script GTM j\xE1 existente. Ignorando reinje\xE7\xE3o.");
|
|
127
226
|
return;
|
|
128
227
|
}
|
|
129
228
|
window.dataLayer = window.dataLayer || [];
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.error("[NineTwo Tracking] Erro ao carregar
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const inlineScript = document.createElement("script");
|
|
148
|
-
inlineScript.setAttribute("data-ninetwo-tracking", `${gtmId}-inline`);
|
|
149
|
-
inlineScript.innerHTML = `
|
|
150
|
-
window.dataLayer = window.dataLayer || [];
|
|
151
|
-
function gtag(){dataLayer.push(arguments);}
|
|
152
|
-
gtag('js', new Date());
|
|
153
|
-
gtag('config', '${gtmId}', {
|
|
154
|
-
send_page_view: true
|
|
155
|
-
});
|
|
156
|
-
`;
|
|
157
|
-
document.head.appendChild(inlineScript);
|
|
158
|
-
}
|
|
159
|
-
if (isGTM) {
|
|
160
|
-
if (debug) {
|
|
161
|
-
console.log("[NineTwo Tracking] Inicializando GTM:", gtmId);
|
|
162
|
-
}
|
|
163
|
-
window.dataLayer.push({
|
|
164
|
-
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
165
|
-
event: "gtm.js"
|
|
166
|
-
});
|
|
167
|
-
const gtmScript = document.createElement("script");
|
|
168
|
-
gtmScript.async = true;
|
|
169
|
-
gtmScript.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
170
|
-
gtmScript.setAttribute("data-ninetwo-tracking", gtmId);
|
|
171
|
-
gtmScript.onload = () => {
|
|
172
|
-
if (debug) {
|
|
173
|
-
console.log("[NineTwo Tracking] GTM carregado com sucesso");
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
gtmScript.onerror = () => {
|
|
177
|
-
console.error("[NineTwo Tracking] Erro ao carregar GTM");
|
|
178
|
-
};
|
|
179
|
-
document.head.appendChild(gtmScript);
|
|
180
|
-
}
|
|
229
|
+
window.dataLayer.push({
|
|
230
|
+
"gtm.start": (/* @__PURE__ */ new Date()).getTime(),
|
|
231
|
+
event: "gtm.js"
|
|
232
|
+
});
|
|
233
|
+
const script = document.createElement("script");
|
|
234
|
+
script.id = scriptId;
|
|
235
|
+
script.async = true;
|
|
236
|
+
script.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`;
|
|
237
|
+
script.onload = () => {
|
|
238
|
+
if (debug)
|
|
239
|
+
console.log(`[NineTwo Tracking] \u2705 GTM carregado com sucesso! (${gtmId})`);
|
|
240
|
+
};
|
|
241
|
+
script.onerror = () => {
|
|
242
|
+
if (debug)
|
|
243
|
+
console.error("[NineTwo Tracking] \u274C Erro ao carregar script do GTM. Verifique AdBlockers.");
|
|
244
|
+
};
|
|
245
|
+
document.head.appendChild(script);
|
|
181
246
|
}, [gtmId, debug]);
|
|
182
247
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
183
248
|
};
|
|
184
249
|
|
|
185
250
|
// src/components/TrackView.tsx
|
|
186
|
-
import { useEffect as
|
|
251
|
+
import { useEffect as useEffect5, useRef, useState } from "react";
|
|
187
252
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
188
253
|
var TrackView = ({
|
|
189
254
|
children,
|
|
@@ -198,7 +263,7 @@ var TrackView = ({
|
|
|
198
263
|
const timerRef = useRef(null);
|
|
199
264
|
const [hasTriggeredView, setHasTriggeredView] = useState(false);
|
|
200
265
|
const [hasTriggeredRead, setHasTriggeredRead] = useState(false);
|
|
201
|
-
|
|
266
|
+
useEffect5(() => {
|
|
202
267
|
const rootEl = ref.current;
|
|
203
268
|
if (!rootEl)
|
|
204
269
|
return;
|