@aranova/tracking-next 0.17.3 → 0.18.1
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 +50 -24
- package/dist/index.d.mts +171 -14
- package/dist/index.d.ts +171 -14
- package/dist/index.js +479 -28
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +457 -9
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +82 -0
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +82 -0
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-DlAQK-gU.d.mts → phone-utils-CVCzW04Z.d.mts} +7 -4
- package/dist/{phone-utils-DlAQK-gU.d.ts → phone-utils-CVCzW04Z.d.ts} +7 -4
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +82 -0
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +82 -0
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-C3jFBx08.d.mts → sales-QqKh6_iy.d.mts} +55 -2
- package/dist/{sales-C3jFBx08.d.ts → sales-QqKh6_iy.d.ts} +55 -2
- package/dist/sales.d.mts +1 -1
- package/dist/sales.d.ts +1 -1
- package/dist/sales.js +16 -0
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +16 -0
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +82 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +82 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -220,6 +220,11 @@ function captureTrackingParamsFromLocation(url = typeof window === "undefined" ?
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// ../tracking-core/src/gtag.ts
|
|
223
|
+
var GTAG_SCRIPT_HOST = "https://www.googletagmanager.com/gtag/js";
|
|
224
|
+
var TRACKING_SCRIPT_ATTRIBUTE = "data-aranova-tracking";
|
|
225
|
+
function getScriptMarker(id) {
|
|
226
|
+
return `aranova-${id}`;
|
|
227
|
+
}
|
|
223
228
|
var GTAG_ID_PATTERN = /^[A-Z]{1,3}-[A-Za-z0-9_-]+$/;
|
|
224
229
|
function isValidGtagId(id) {
|
|
225
230
|
return GTAG_ID_PATTERN.test(id);
|
|
@@ -248,6 +253,15 @@ gtag('js', new Date());
|
|
|
248
253
|
gtag('config', '${gtagId}');
|
|
249
254
|
`.trim();
|
|
250
255
|
}
|
|
256
|
+
function ensureGtagFunction() {
|
|
257
|
+
window.dataLayer = window.dataLayer || [];
|
|
258
|
+
if (typeof window.gtag === "function") return window.gtag;
|
|
259
|
+
function gtag() {
|
|
260
|
+
window.dataLayer?.push(arguments);
|
|
261
|
+
}
|
|
262
|
+
window.gtag = gtag;
|
|
263
|
+
return window.gtag;
|
|
264
|
+
}
|
|
251
265
|
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
252
266
|
function isValidSendTo(sendTo) {
|
|
253
267
|
return SEND_TO_RE.test(sendTo);
|
|
@@ -266,6 +280,27 @@ function fireGtagConversion(input) {
|
|
|
266
280
|
return false;
|
|
267
281
|
}
|
|
268
282
|
}
|
|
283
|
+
function applyDefaultConsentState() {
|
|
284
|
+
const gtag = ensureGtagFunction();
|
|
285
|
+
gtag(
|
|
286
|
+
"consent",
|
|
287
|
+
"default",
|
|
288
|
+
buildConsentPayload(getConsentState() === "denied" ? "denied" : "granted")
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
function loadGtagScript(gtagId) {
|
|
292
|
+
if (typeof document === "undefined") return;
|
|
293
|
+
const marker = getScriptMarker("gtag-loader");
|
|
294
|
+
const existingScript = document.querySelector(
|
|
295
|
+
`script[${TRACKING_SCRIPT_ATTRIBUTE}="${marker}"]`
|
|
296
|
+
);
|
|
297
|
+
if (existingScript) return;
|
|
298
|
+
const script = document.createElement("script");
|
|
299
|
+
script.async = true;
|
|
300
|
+
script.src = `${GTAG_SCRIPT_HOST}?id=${encodeURIComponent(gtagId)}`;
|
|
301
|
+
script.setAttribute(TRACKING_SCRIPT_ATTRIBUTE, marker);
|
|
302
|
+
document.head.append(script);
|
|
303
|
+
}
|
|
269
304
|
function createGtagInitScriptMulti(gtagIds) {
|
|
270
305
|
const safeIds = gtagIds.filter(isValidGtagId);
|
|
271
306
|
const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
|
|
@@ -552,6 +587,7 @@ function parseConversionConfig(raw) {
|
|
|
552
587
|
business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
|
|
553
588
|
customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
|
|
554
589
|
environment: typeof obj.environment === "string" ? obj.environment : void 0,
|
|
590
|
+
google_tracking_state: obj.google_tracking_state === "active" ? "active" : "disabled",
|
|
555
591
|
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
556
592
|
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
557
593
|
services,
|
|
@@ -687,6 +723,283 @@ function formatDateInTz(iso, timeZone, opts, locale) {
|
|
|
687
723
|
}).format(date);
|
|
688
724
|
}
|
|
689
725
|
|
|
726
|
+
// ../tracking-core/src/resources/tracking-config-runtime.ts
|
|
727
|
+
var CACHE_PREFIX2 = "_aranova_cfg_runtime_";
|
|
728
|
+
var AUTHORITY_TTL_MS = 6e4;
|
|
729
|
+
var runtimes = /* @__PURE__ */ new Map();
|
|
730
|
+
var configuredIds = /* @__PURE__ */ new Set();
|
|
731
|
+
var scriptLoad = null;
|
|
732
|
+
var jsInitialized = false;
|
|
733
|
+
function cacheKey2(url) {
|
|
734
|
+
return `${CACHE_PREFIX2}${url}`;
|
|
735
|
+
}
|
|
736
|
+
function readCache2(url) {
|
|
737
|
+
if (typeof window === "undefined") return null;
|
|
738
|
+
try {
|
|
739
|
+
const raw = window.sessionStorage.getItem(cacheKey2(url));
|
|
740
|
+
if (!raw) return null;
|
|
741
|
+
const parsed = JSON.parse(raw);
|
|
742
|
+
const config = parseConversionConfig(parsed.config);
|
|
743
|
+
if (!config) return null;
|
|
744
|
+
return {
|
|
745
|
+
etag: typeof parsed.etag === "string" ? parsed.etag : null,
|
|
746
|
+
config
|
|
747
|
+
};
|
|
748
|
+
} catch {
|
|
749
|
+
return null;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function writeCache2(url, entry) {
|
|
753
|
+
if (typeof window === "undefined") return;
|
|
754
|
+
try {
|
|
755
|
+
window.sessionStorage.setItem(cacheKey2(url), JSON.stringify(entry));
|
|
756
|
+
} catch {
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
function isTombstone(config) {
|
|
760
|
+
return config.google_tracking_state === "disabled" || Object.keys(config.gtag_ids).length === 0;
|
|
761
|
+
}
|
|
762
|
+
function validateConfig(config, ref) {
|
|
763
|
+
return config.business_id === ref.businessId && config.environment === ref.environment && (config.google_tracking_state === "active" || config.google_tracking_state === "disabled");
|
|
764
|
+
}
|
|
765
|
+
function pageViewSnapshot() {
|
|
766
|
+
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
767
|
+
return {
|
|
768
|
+
href: window.location.href,
|
|
769
|
+
title: document.title || null,
|
|
770
|
+
referrer: document.referrer || null
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
function ensureScript(gtagId) {
|
|
774
|
+
if (typeof window === "undefined" || typeof document === "undefined") return Promise.resolve();
|
|
775
|
+
applyDefaultConsentState();
|
|
776
|
+
loadGtagScript(gtagId);
|
|
777
|
+
if (scriptLoad) return scriptLoad;
|
|
778
|
+
scriptLoad = new Promise((resolve) => {
|
|
779
|
+
const script = document.querySelector(
|
|
780
|
+
'script[data-aranova-tracking="aranova-gtag-loader"]'
|
|
781
|
+
);
|
|
782
|
+
if (!script) {
|
|
783
|
+
resolve();
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (script.dataset.loaded === "true") {
|
|
787
|
+
resolve();
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
window.setTimeout(resolve, 0);
|
|
791
|
+
script.addEventListener(
|
|
792
|
+
"load",
|
|
793
|
+
() => {
|
|
794
|
+
script.dataset.loaded = "true";
|
|
795
|
+
resolve();
|
|
796
|
+
},
|
|
797
|
+
{ once: true }
|
|
798
|
+
);
|
|
799
|
+
script.addEventListener("error", () => resolve(), { once: true });
|
|
800
|
+
});
|
|
801
|
+
return scriptLoad;
|
|
802
|
+
}
|
|
803
|
+
var TrackingConfigRuntime = class {
|
|
804
|
+
constructor(ref, fetchImpl = globalThis.fetch) {
|
|
805
|
+
this.ref = ref;
|
|
806
|
+
this.fetchImpl = fetchImpl;
|
|
807
|
+
this.current = null;
|
|
808
|
+
this.etag = null;
|
|
809
|
+
this.stateValue = "unconfirmed";
|
|
810
|
+
this.confirmedAt = 0;
|
|
811
|
+
this.inFlight = null;
|
|
812
|
+
this.conversionQueue = [];
|
|
813
|
+
this.automaticQueue = [];
|
|
814
|
+
this.pageQueue = [];
|
|
815
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
816
|
+
const cached = readCache2(ref.cdnUrl);
|
|
817
|
+
this.current = cached?.config ?? null;
|
|
818
|
+
this.etag = cached?.etag ?? null;
|
|
819
|
+
void this.revalidate();
|
|
820
|
+
if (typeof window !== "undefined") {
|
|
821
|
+
window.addEventListener("visibilitychange", () => {
|
|
822
|
+
if (document.visibilityState === "visible") void this.revalidate();
|
|
823
|
+
});
|
|
824
|
+
window.addEventListener("focus", () => void this.revalidate());
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
state() {
|
|
828
|
+
return this.stateValue;
|
|
829
|
+
}
|
|
830
|
+
config() {
|
|
831
|
+
return this.stateValue === "active" || this.stateValue === "tombstone" ? this.current : null;
|
|
832
|
+
}
|
|
833
|
+
__unsafeExpireAuthorityForTests() {
|
|
834
|
+
this.confirmedAt = 0;
|
|
835
|
+
}
|
|
836
|
+
subscribe(listener) {
|
|
837
|
+
this.listeners.add(listener);
|
|
838
|
+
return () => this.listeners.delete(listener);
|
|
839
|
+
}
|
|
840
|
+
async ensureAuthority() {
|
|
841
|
+
if (this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS) {
|
|
842
|
+
return true;
|
|
843
|
+
}
|
|
844
|
+
await this.revalidate();
|
|
845
|
+
return this.stateValue !== "unconfirmed" && Date.now() - this.confirmedAt < AUTHORITY_TTL_MS;
|
|
846
|
+
}
|
|
847
|
+
async revalidate() {
|
|
848
|
+
if (typeof window === "undefined" || !this.fetchImpl) return;
|
|
849
|
+
if (this.inFlight) return this.inFlight;
|
|
850
|
+
this.inFlight = this.revalidateNow().finally(() => {
|
|
851
|
+
this.inFlight = null;
|
|
852
|
+
});
|
|
853
|
+
return this.inFlight;
|
|
854
|
+
}
|
|
855
|
+
queuePageView(snapshot = pageViewSnapshot()) {
|
|
856
|
+
if (!snapshot) return;
|
|
857
|
+
this.pageQueue.push(snapshot);
|
|
858
|
+
void this.flush();
|
|
859
|
+
}
|
|
860
|
+
fireConversion(key, options) {
|
|
861
|
+
this.conversionQueue.push({ key, ...options });
|
|
862
|
+
void this.flush();
|
|
863
|
+
}
|
|
864
|
+
queueAutomaticEvent(eventType, metadata, transactionPath) {
|
|
865
|
+
this.automaticQueue.push({ eventType, metadata, transactionPath });
|
|
866
|
+
void this.flush();
|
|
867
|
+
}
|
|
868
|
+
listGoals() {
|
|
869
|
+
return this.current?.goals ?? [];
|
|
870
|
+
}
|
|
871
|
+
async revalidateNow() {
|
|
872
|
+
try {
|
|
873
|
+
const headers = {};
|
|
874
|
+
if (this.etag) headers["If-None-Match"] = this.etag;
|
|
875
|
+
const response = await this.fetchImpl(this.ref.cdnUrl, {
|
|
876
|
+
method: "GET",
|
|
877
|
+
headers,
|
|
878
|
+
cache: "no-cache"
|
|
879
|
+
});
|
|
880
|
+
if (response.status === 304 && this.current && validateConfig(this.current, this.ref)) {
|
|
881
|
+
this.confirm(this.current, this.etag);
|
|
882
|
+
await this.flush();
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
if (!response.ok) {
|
|
886
|
+
this.expireAuthority();
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
const next = parseConversionConfig(await response.json());
|
|
890
|
+
if (!next || !validateConfig(next, this.ref)) {
|
|
891
|
+
this.expireAuthority();
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (this.current && next.config_version < this.current.config_version) {
|
|
895
|
+
this.expireAuthority();
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
this.confirm(next, response.headers.get("ETag"));
|
|
899
|
+
await this.flush();
|
|
900
|
+
} catch {
|
|
901
|
+
this.expireAuthority();
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
expireAuthority() {
|
|
905
|
+
if (this.stateValue !== "unconfirmed") this.stateValue = "unconfirmed";
|
|
906
|
+
}
|
|
907
|
+
confirm(config, etag) {
|
|
908
|
+
this.current = config;
|
|
909
|
+
this.etag = etag;
|
|
910
|
+
this.confirmedAt = Date.now();
|
|
911
|
+
this.stateValue = isTombstone(config) ? "tombstone" : "active";
|
|
912
|
+
writeCache2(this.ref.cdnUrl, { etag, config });
|
|
913
|
+
if (this.stateValue === "tombstone") {
|
|
914
|
+
this.conversionQueue.length = 0;
|
|
915
|
+
this.automaticQueue.length = 0;
|
|
916
|
+
this.pageQueue.length = 0;
|
|
917
|
+
}
|
|
918
|
+
for (const listener of this.listeners) listener();
|
|
919
|
+
}
|
|
920
|
+
async flush() {
|
|
921
|
+
if (!await this.ensureAuthority()) return;
|
|
922
|
+
if (this.stateValue !== "active" || !this.current) return;
|
|
923
|
+
const ids = Object.values(this.current.gtag_ids).filter(
|
|
924
|
+
(id) => typeof id === "string" && isValidGtagId(id)
|
|
925
|
+
);
|
|
926
|
+
if (ids.length === 0) return;
|
|
927
|
+
await ensureScript(ids[0]);
|
|
928
|
+
const gtag = window.gtag;
|
|
929
|
+
if (typeof gtag !== "function") return;
|
|
930
|
+
if (!jsInitialized) {
|
|
931
|
+
gtag("js", /* @__PURE__ */ new Date());
|
|
932
|
+
jsInitialized = true;
|
|
933
|
+
}
|
|
934
|
+
for (const id of ids) {
|
|
935
|
+
if (configuredIds.has(id)) continue;
|
|
936
|
+
gtag("config", id, { send_page_view: false });
|
|
937
|
+
configuredIds.add(id);
|
|
938
|
+
}
|
|
939
|
+
while (this.pageQueue.length) {
|
|
940
|
+
const page = this.pageQueue.shift();
|
|
941
|
+
gtag("event", "page_view", {
|
|
942
|
+
page_location: page.href,
|
|
943
|
+
page_title: page.title ?? void 0,
|
|
944
|
+
page_referrer: page.referrer ?? void 0
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
while (this.automaticQueue.length) {
|
|
948
|
+
const event = this.automaticQueue.shift();
|
|
949
|
+
for (const goal of this.current.goals) {
|
|
950
|
+
if (goal.kind !== "event" || !goal.firing) continue;
|
|
951
|
+
if (!automaticThresholdMet(goal, event.eventType, event.metadata)) continue;
|
|
952
|
+
this.conversionQueue.push({
|
|
953
|
+
key: goal.key,
|
|
954
|
+
transactionId: `auto:${goal.key}:${event.transactionPath}`
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
while (this.conversionQueue.length) {
|
|
959
|
+
const item = this.conversionQueue.shift();
|
|
960
|
+
const goal = this.current.goals.find((g) => g.key === item.key);
|
|
961
|
+
const firing = goal?.firing;
|
|
962
|
+
if (!firing || getConsentState() === "denied") continue;
|
|
963
|
+
const currency = item.currency ?? firing.currency ?? null;
|
|
964
|
+
const value = item.value ?? (firing.value_cents != null && currency ? fromMinor(firing.value_cents, currency) : null);
|
|
965
|
+
fireGtagConversion({
|
|
966
|
+
sendTo: firing.send_to,
|
|
967
|
+
value,
|
|
968
|
+
currency,
|
|
969
|
+
transactionId: item.transactionId ?? null
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
function automaticThresholdMet(goal, eventType, metadata) {
|
|
975
|
+
const t = goal.trigger;
|
|
976
|
+
if (!t || t.event_type !== eventType) return false;
|
|
977
|
+
switch (eventType) {
|
|
978
|
+
case "scroll_depth":
|
|
979
|
+
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
980
|
+
case "time_on_site":
|
|
981
|
+
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
982
|
+
case "multi_page_session":
|
|
983
|
+
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
984
|
+
case "specific_page_visit":
|
|
985
|
+
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
986
|
+
case "page_view":
|
|
987
|
+
case "form_start":
|
|
988
|
+
case "phone_click":
|
|
989
|
+
return true;
|
|
990
|
+
default:
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
function getTrackingConfigRuntime(ref, fetchImpl) {
|
|
995
|
+
const key = `${ref.cdnUrl}|${ref.businessId}|${ref.environment}`;
|
|
996
|
+
const existing = runtimes.get(key);
|
|
997
|
+
if (existing) return existing;
|
|
998
|
+
const runtime = new TrackingConfigRuntime(ref, fetchImpl ?? globalThis.fetch);
|
|
999
|
+
runtimes.set(key, runtime);
|
|
1000
|
+
return runtime;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
690
1003
|
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
691
1004
|
function thresholdMet(goal, eventType, metadata) {
|
|
692
1005
|
const t = goal.trigger;
|
|
@@ -719,6 +1032,12 @@ function createConversionAutoFire(store) {
|
|
|
719
1032
|
for (const goal of store.listGoals()) {
|
|
720
1033
|
if (goal.kind !== "event" || !goal.firing) continue;
|
|
721
1034
|
if (!thresholdMet(goal, eventType, metadata)) continue;
|
|
1035
|
+
if ("queueAutomaticEvent" in store) {
|
|
1036
|
+
store.fireConversion(goal.key, {
|
|
1037
|
+
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
1038
|
+
});
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
722
1041
|
const firing = goal.firing;
|
|
723
1042
|
const cents = firing.value_cents ?? null;
|
|
724
1043
|
const currency = firing.currency ?? null;
|
|
@@ -734,6 +1053,10 @@ function createConversionAutoFire(store) {
|
|
|
734
1053
|
}
|
|
735
1054
|
return {
|
|
736
1055
|
onAutomaticEvent(eventType, metadata) {
|
|
1056
|
+
if ("queueAutomaticEvent" in store) {
|
|
1057
|
+
store.queueAutomaticEvent(eventType, metadata, currentPath());
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
737
1060
|
if (store.isReady()) {
|
|
738
1061
|
fireMatching(eventType, metadata);
|
|
739
1062
|
return;
|
|
@@ -1413,69 +1736,154 @@ var timeOnSiteConfigSchema = z11.object({
|
|
|
1413
1736
|
thresholdSeconds: z11.number().int().positive()
|
|
1414
1737
|
}).strict();
|
|
1415
1738
|
|
|
1739
|
+
// ../tracking-core/src/events/semantics.ts
|
|
1740
|
+
var EVENT_SEMANTICS = {
|
|
1741
|
+
page_view: {
|
|
1742
|
+
label: "Page view",
|
|
1743
|
+
category: "page",
|
|
1744
|
+
outcomeRole: "navigation",
|
|
1745
|
+
clientVisibility: "simple"
|
|
1746
|
+
},
|
|
1747
|
+
time_on_site: {
|
|
1748
|
+
label: "Time on site",
|
|
1749
|
+
category: "engagement",
|
|
1750
|
+
outcomeRole: "engagement",
|
|
1751
|
+
clientVisibility: "detailed"
|
|
1752
|
+
},
|
|
1753
|
+
specific_page_visit: {
|
|
1754
|
+
label: "Key page visit",
|
|
1755
|
+
category: "engagement",
|
|
1756
|
+
outcomeRole: "engagement",
|
|
1757
|
+
clientVisibility: "detailed"
|
|
1758
|
+
},
|
|
1759
|
+
scroll_depth: {
|
|
1760
|
+
label: "Scroll depth",
|
|
1761
|
+
category: "engagement",
|
|
1762
|
+
outcomeRole: "engagement",
|
|
1763
|
+
clientVisibility: "detailed"
|
|
1764
|
+
},
|
|
1765
|
+
multi_page_session: {
|
|
1766
|
+
label: "Multi-page session",
|
|
1767
|
+
category: "engagement",
|
|
1768
|
+
outcomeRole: "engagement",
|
|
1769
|
+
clientVisibility: "detailed"
|
|
1770
|
+
},
|
|
1771
|
+
form_start: {
|
|
1772
|
+
label: "Form started",
|
|
1773
|
+
category: "engagement",
|
|
1774
|
+
outcomeRole: "engagement",
|
|
1775
|
+
clientVisibility: "simple"
|
|
1776
|
+
},
|
|
1777
|
+
sdk_heartbeat: {
|
|
1778
|
+
label: "SDK heartbeat",
|
|
1779
|
+
category: "system",
|
|
1780
|
+
outcomeRole: "diagnostic",
|
|
1781
|
+
clientVisibility: "hidden"
|
|
1782
|
+
},
|
|
1783
|
+
page_exit: {
|
|
1784
|
+
label: "Page exit",
|
|
1785
|
+
category: "engagement",
|
|
1786
|
+
outcomeRole: "diagnostic",
|
|
1787
|
+
clientVisibility: "detailed"
|
|
1788
|
+
},
|
|
1789
|
+
form_submit: {
|
|
1790
|
+
label: "Form submitted",
|
|
1791
|
+
category: "lead",
|
|
1792
|
+
outcomeRole: "lead",
|
|
1793
|
+
clientVisibility: "simple"
|
|
1794
|
+
},
|
|
1795
|
+
phone_click: {
|
|
1796
|
+
label: "Phone click",
|
|
1797
|
+
category: "lead",
|
|
1798
|
+
outcomeRole: "lead",
|
|
1799
|
+
clientVisibility: "simple"
|
|
1800
|
+
},
|
|
1801
|
+
cta_click: {
|
|
1802
|
+
label: "CTA click",
|
|
1803
|
+
category: "engagement",
|
|
1804
|
+
outcomeRole: "engagement",
|
|
1805
|
+
clientVisibility: "simple"
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1808
|
+
function getEventSemantics(eventName) {
|
|
1809
|
+
return eventName in EVENT_SEMANTICS ? EVENT_SEMANTICS[eventName] : null;
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1416
1812
|
// ../tracking-core/src/events/registry.ts
|
|
1417
1813
|
var EVENT_REGISTRY = {
|
|
1418
1814
|
// --- automatic triggers ---
|
|
1419
1815
|
page_view: {
|
|
1420
1816
|
kind: "automatic",
|
|
1817
|
+
semantics: EVENT_SEMANTICS.page_view,
|
|
1421
1818
|
metadataSchema: pageViewMetadataSchema,
|
|
1422
1819
|
configSchema: pageViewConfigSchema
|
|
1423
1820
|
},
|
|
1424
1821
|
time_on_site: {
|
|
1425
1822
|
kind: "automatic",
|
|
1823
|
+
semantics: EVENT_SEMANTICS.time_on_site,
|
|
1426
1824
|
metadataSchema: timeOnSiteMetadataSchema,
|
|
1427
1825
|
configSchema: timeOnSiteConfigSchema
|
|
1428
1826
|
},
|
|
1429
1827
|
specific_page_visit: {
|
|
1430
1828
|
kind: "automatic",
|
|
1829
|
+
semantics: EVENT_SEMANTICS.specific_page_visit,
|
|
1431
1830
|
metadataSchema: specificPageVisitMetadataSchema,
|
|
1432
1831
|
configSchema: specificPageVisitConfigSchema
|
|
1433
1832
|
},
|
|
1434
1833
|
scroll_depth: {
|
|
1435
1834
|
kind: "automatic",
|
|
1835
|
+
semantics: EVENT_SEMANTICS.scroll_depth,
|
|
1436
1836
|
metadataSchema: scrollDepthMetadataSchema,
|
|
1437
1837
|
configSchema: scrollDepthConfigSchema
|
|
1438
1838
|
},
|
|
1439
1839
|
multi_page_session: {
|
|
1440
1840
|
kind: "automatic",
|
|
1841
|
+
semantics: EVENT_SEMANTICS.multi_page_session,
|
|
1441
1842
|
metadataSchema: multiPageSessionMetadataSchema,
|
|
1442
1843
|
configSchema: multiPageSessionConfigSchema
|
|
1443
1844
|
},
|
|
1444
1845
|
form_start: {
|
|
1445
1846
|
kind: "automatic",
|
|
1847
|
+
semantics: EVENT_SEMANTICS.form_start,
|
|
1446
1848
|
metadataSchema: formStartMetadataSchema,
|
|
1447
1849
|
configSchema: formStartConfigSchema
|
|
1448
1850
|
},
|
|
1449
1851
|
// --- SDK-internal automatic (not consumer-configurable) ---
|
|
1450
1852
|
sdk_heartbeat: {
|
|
1451
1853
|
kind: "automatic",
|
|
1854
|
+
semantics: EVENT_SEMANTICS.sdk_heartbeat,
|
|
1452
1855
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1453
1856
|
configSchema: sdkHeartbeatConfigSchema
|
|
1454
1857
|
},
|
|
1455
1858
|
page_exit: {
|
|
1456
1859
|
kind: "automatic",
|
|
1860
|
+
semantics: EVENT_SEMANTICS.page_exit,
|
|
1457
1861
|
metadataSchema: pageExitMetadataSchema,
|
|
1458
1862
|
configSchema: pageExitConfigSchema
|
|
1459
1863
|
},
|
|
1460
1864
|
// --- manual triggers ---
|
|
1461
1865
|
form_submit: {
|
|
1462
1866
|
kind: "manual",
|
|
1867
|
+
semantics: EVENT_SEMANTICS.form_submit,
|
|
1463
1868
|
metadataSchema: formSubmitMetadataSchema,
|
|
1464
1869
|
configSchema: formSubmitConfigSchema
|
|
1465
1870
|
},
|
|
1466
1871
|
phone_click: {
|
|
1467
1872
|
kind: "manual",
|
|
1873
|
+
semantics: EVENT_SEMANTICS.phone_click,
|
|
1468
1874
|
metadataSchema: phoneClickMetadataSchema,
|
|
1469
1875
|
configSchema: phoneClickConfigSchema
|
|
1470
1876
|
},
|
|
1471
1877
|
cta_click: {
|
|
1472
1878
|
kind: "manual",
|
|
1879
|
+
semantics: EVENT_SEMANTICS.cta_click,
|
|
1473
1880
|
metadataSchema: ctaClickMetadataSchema,
|
|
1474
1881
|
configSchema: ctaClickConfigSchema
|
|
1475
1882
|
}
|
|
1476
1883
|
};
|
|
1477
1884
|
var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
|
|
1478
1885
|
var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
|
|
1886
|
+
var ALL_LEAD_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.semantics.outcomeRole === "lead").map(([name]) => name);
|
|
1479
1887
|
function getEventDefinition(name) {
|
|
1480
1888
|
return EVENT_REGISTRY[name];
|
|
1481
1889
|
}
|
|
@@ -2073,6 +2481,14 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
|
2073
2481
|
const txnBase = input.external_id ?? sale.id;
|
|
2074
2482
|
for (const item of recorded) {
|
|
2075
2483
|
if (!item.service) continue;
|
|
2484
|
+
if ("fireConversion" in firing) {
|
|
2485
|
+
firing.fireConversion(item.service, {
|
|
2486
|
+
value: item.amount_cents != null ? fromMinor(item.amount_cents, currency) : void 0,
|
|
2487
|
+
currency,
|
|
2488
|
+
transactionId: `${txnBase}:${item.service}`
|
|
2489
|
+
});
|
|
2490
|
+
continue;
|
|
2491
|
+
}
|
|
2076
2492
|
const config = firing.getFiring(item.service);
|
|
2077
2493
|
if (!config) continue;
|
|
2078
2494
|
const cents = item.amount_cents ?? config.value_cents ?? null;
|
|
@@ -2115,6 +2531,14 @@ function createSalesClient(config) {
|
|
|
2115
2531
|
// recordSale is the intent-revealing alias — same behavior, clearer call site.
|
|
2116
2532
|
recordSale: record,
|
|
2117
2533
|
trackConversion(key, options) {
|
|
2534
|
+
if (config.firing && "fireConversion" in config.firing) {
|
|
2535
|
+
config.firing.fireConversion(key, {
|
|
2536
|
+
value: options?.value ?? void 0,
|
|
2537
|
+
currency: options?.currency ?? config.defaultCurrency ?? void 0,
|
|
2538
|
+
transactionId: options?.transactionId ?? null
|
|
2539
|
+
});
|
|
2540
|
+
return;
|
|
2541
|
+
}
|
|
2118
2542
|
const firing = config.firing?.getFiring(key);
|
|
2119
2543
|
if (!firing) return;
|
|
2120
2544
|
const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
|
|
@@ -2620,14 +3044,24 @@ var ANIMATION_KEYFRAMES = `
|
|
|
2620
3044
|
|
|
2621
3045
|
// src/AdPlatformTracking.tsx
|
|
2622
3046
|
import Script from "next/script";
|
|
3047
|
+
import { useEffect as useEffect3 } from "react";
|
|
2623
3048
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2624
3049
|
function AdPlatformTracking({
|
|
2625
3050
|
gtagId,
|
|
2626
3051
|
gtagIds,
|
|
3052
|
+
trackingConfig,
|
|
3053
|
+
standalonePageView = false,
|
|
2627
3054
|
metaPixelId,
|
|
2628
3055
|
metaPixelIds
|
|
2629
3056
|
}) {
|
|
2630
|
-
const
|
|
3057
|
+
const trackingConfigKey = trackingConfig ? `${trackingConfig.cdnUrl}:${trackingConfig.businessId}:${trackingConfig.environment}` : "";
|
|
3058
|
+
useEffect3(() => {
|
|
3059
|
+
if (!trackingConfig) return;
|
|
3060
|
+
const runtime = getTrackingConfigRuntime(trackingConfig);
|
|
3061
|
+
if (standalonePageView) runtime.queuePageView();
|
|
3062
|
+
else void runtime.revalidate();
|
|
3063
|
+
}, [trackingConfigKey, standalonePageView]);
|
|
3064
|
+
const gtagAll = trackingConfig ? [] : gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
|
|
2631
3065
|
const metaAll = metaPixelIds ? Object.values(metaPixelIds).filter((id) => id != null) : metaPixelId ? [metaPixelId] : [];
|
|
2632
3066
|
const gtagLoaderId = gtagAll[0];
|
|
2633
3067
|
const gtagInitScript = gtagAll.length === 1 ? createGtagInitScript(gtagAll[0]) : createGtagInitScriptMulti(gtagAll);
|
|
@@ -2677,7 +3111,7 @@ function GoogleAdsTracking(props) {
|
|
|
2677
3111
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
2678
3112
|
|
|
2679
3113
|
// package.json
|
|
2680
|
-
var version = "0.
|
|
3114
|
+
var version = "0.18.1";
|
|
2681
3115
|
|
|
2682
3116
|
// src/factory.tsx
|
|
2683
3117
|
import {
|
|
@@ -2685,7 +3119,7 @@ import {
|
|
|
2685
3119
|
Suspense,
|
|
2686
3120
|
useCallback as useCallback3,
|
|
2687
3121
|
useContext as useContext2,
|
|
2688
|
-
useEffect as
|
|
3122
|
+
useEffect as useEffect4,
|
|
2689
3123
|
useMemo as useMemo2,
|
|
2690
3124
|
useRef
|
|
2691
3125
|
} from "react";
|
|
@@ -2788,13 +3222,23 @@ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
2788
3222
|
function PageViewTracker({ fire }) {
|
|
2789
3223
|
const pathname = usePathname();
|
|
2790
3224
|
const searchParams = useSearchParams();
|
|
2791
|
-
|
|
3225
|
+
useEffect4(() => {
|
|
2792
3226
|
fire();
|
|
2793
3227
|
}, [pathname, searchParams, fire]);
|
|
2794
3228
|
return null;
|
|
2795
3229
|
}
|
|
2796
3230
|
function createTracking(options) {
|
|
2797
|
-
const {
|
|
3231
|
+
const {
|
|
3232
|
+
apiKey,
|
|
3233
|
+
endpoint,
|
|
3234
|
+
triggers,
|
|
3235
|
+
environment,
|
|
3236
|
+
gtagIds,
|
|
3237
|
+
debug,
|
|
3238
|
+
phone,
|
|
3239
|
+
conversionConfig,
|
|
3240
|
+
trackingConfig
|
|
3241
|
+
} = options;
|
|
2798
3242
|
if (!apiKey || !endpoint) {
|
|
2799
3243
|
if (apiKey || endpoint) {
|
|
2800
3244
|
console.warn(
|
|
@@ -2838,7 +3282,7 @@ function createTracking(options) {
|
|
|
2838
3282
|
[]
|
|
2839
3283
|
);
|
|
2840
3284
|
const conversionStore = useMemo2(
|
|
2841
|
-
() => conversionConfig ? resolveConversionConfig({
|
|
3285
|
+
() => trackingConfig ? getTrackingConfigRuntime(trackingConfig) : conversionConfig ? resolveConversionConfig({
|
|
2842
3286
|
cdnUrl: conversionConfig.cdnUrl,
|
|
2843
3287
|
baked: conversionConfig.baked
|
|
2844
3288
|
}) : null,
|
|
@@ -2860,9 +3304,10 @@ function createTracking(options) {
|
|
|
2860
3304
|
debug
|
|
2861
3305
|
});
|
|
2862
3306
|
fireManualPageView(wrapClient(rawClient));
|
|
3307
|
+
if (trackingConfig) getTrackingConfigRuntime(trackingConfig).queuePageView();
|
|
2863
3308
|
}, [wrapClient]);
|
|
2864
3309
|
const firedPagesRef = useRef(/* @__PURE__ */ new Set());
|
|
2865
|
-
|
|
3310
|
+
useEffect4(() => {
|
|
2866
3311
|
if (!specificPageVisitConfig || pathname === null) return;
|
|
2867
3312
|
const rawClient = getOrCreateTrackingClient({
|
|
2868
3313
|
apiKey,
|
|
@@ -2893,7 +3338,7 @@ function createTracking(options) {
|
|
|
2893
3338
|
}, [pathname]);
|
|
2894
3339
|
const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
|
|
2895
3340
|
const mpsLastPathRef = useRef(null);
|
|
2896
|
-
|
|
3341
|
+
useEffect4(() => {
|
|
2897
3342
|
if (!multiPageSessionConfig || pathname === null) return;
|
|
2898
3343
|
if (pathname === mpsLastPathRef.current) return;
|
|
2899
3344
|
mpsLastPathRef.current = pathname;
|
|
@@ -2940,7 +3385,7 @@ function createTracking(options) {
|
|
|
2940
3385
|
} catch {
|
|
2941
3386
|
}
|
|
2942
3387
|
}, [pathname]);
|
|
2943
|
-
|
|
3388
|
+
useEffect4(() => {
|
|
2944
3389
|
const rawClient = getOrCreateTrackingClient({
|
|
2945
3390
|
apiKey,
|
|
2946
3391
|
endpoint,
|
|
@@ -3004,6 +3449,7 @@ export {
|
|
|
3004
3449
|
ConsentBanner,
|
|
3005
3450
|
DEFAULT_DECLINE_TTL_DAYS,
|
|
3006
3451
|
DEFAULT_PHONE_COUNTRY,
|
|
3452
|
+
EVENT_SEMANTICS,
|
|
3007
3453
|
GoogleAdsTracking,
|
|
3008
3454
|
NAMED_RANGES,
|
|
3009
3455
|
PhoneField,
|
|
@@ -3024,6 +3470,8 @@ export {
|
|
|
3024
3470
|
fromMinor,
|
|
3025
3471
|
getConsentChoice,
|
|
3026
3472
|
getConsentState,
|
|
3473
|
+
getEventSemantics,
|
|
3474
|
+
getTrackingConfigRuntime,
|
|
3027
3475
|
onConsentChange,
|
|
3028
3476
|
optIn,
|
|
3029
3477
|
optOut,
|