@callforge/tracking-client 0.6.1 → 0.6.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.
- package/README.md +8 -7
- package/dist/index.d.mts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +85 -4
- package/dist/index.mjs +85 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,23 +67,24 @@ Notes:
|
|
|
67
67
|
|
|
68
68
|
### 4. GA4 Integration
|
|
69
69
|
|
|
70
|
-
To enable GA4 call event tracking,
|
|
70
|
+
To enable GA4 call event tracking, CallForge needs the GA4 `client_id` for the visitor (from the `_ga` cookie).
|
|
71
|
+
Optionally provide your GA4 Measurement ID to improve client ID capture reliability when Google Analytics loads late.
|
|
71
72
|
|
|
72
73
|
```typescript
|
|
73
74
|
const client = CallForge.init({
|
|
74
75
|
categoryId: 'your-category-id',
|
|
75
|
-
ga4MeasurementId: 'G-XXXXXXXXXX',
|
|
76
|
+
ga4MeasurementId: 'G-XXXXXXXXXX', // Recommended
|
|
76
77
|
});
|
|
77
78
|
```
|
|
78
79
|
|
|
79
80
|
Requirements:
|
|
80
|
-
1. Google Analytics 4 must be installed on your site (
|
|
81
|
-
2.
|
|
82
|
-
3. Configure GA4 credentials in CallForge dashboard.
|
|
81
|
+
1. Google Analytics 4 must be installed on your site and allowed to set the `_ga` cookie (gtag.js or GTM).
|
|
82
|
+
2. Configure GA4 credentials in CallForge dashboard (Measurement ID + API secret).
|
|
83
83
|
|
|
84
84
|
How it works:
|
|
85
|
-
-
|
|
86
|
-
-
|
|
85
|
+
- Extracts the GA4 `client_id` from the `_ga` cookie and sends it to CallForge as `ga4ClientId`.
|
|
86
|
+
- If `ga4MeasurementId` is configured and `gtag` is available, also uses `gtag('get', measurementId, 'client_id', ...)` (with a short retry window).
|
|
87
|
+
- If `ga4ClientId` becomes available after a session is created, the client will refresh once to sync it to CallForge.
|
|
87
88
|
|
|
88
89
|
Manual override:
|
|
89
90
|
|
package/dist/index.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ interface CallForgeConfig {
|
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
/** Optional - explicit site key for cache partitioning. Defaults to window.location.hostname */
|
|
10
10
|
siteKey?: string;
|
|
11
|
-
/** Optional - GA4 Measurement ID (e.g., "G-XXXXXXXXXX"). Enables gtag
|
|
11
|
+
/** Optional - GA4 Measurement ID (e.g., "G-XXXXXXXXXX"). Enables gtag-based client_id capture for late-loading GA. */
|
|
12
12
|
ga4MeasurementId?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
@@ -121,10 +121,20 @@ declare class CallForge {
|
|
|
121
121
|
*/
|
|
122
122
|
getQueuedParams(): TrackingParams;
|
|
123
123
|
/**
|
|
124
|
-
* Capture the GA4 client ID
|
|
125
|
-
*
|
|
124
|
+
* Capture the GA4 client ID.
|
|
125
|
+
*
|
|
126
|
+
* Prefer `_ga` cookie parsing (works even when gtag is not loaded yet).
|
|
127
|
+
* If ga4MeasurementId is configured and gtag is available, use gtag as a fallback.
|
|
126
128
|
*/
|
|
127
129
|
private captureGA4ClientId;
|
|
130
|
+
private startGA4ClientIdPolling;
|
|
131
|
+
/**
|
|
132
|
+
* Extract GA4 client_id from the `_ga` cookie.
|
|
133
|
+
*
|
|
134
|
+
* Example cookie value: `GA1.1.1234567890.1234567890`
|
|
135
|
+
* Returns: `1234567890.1234567890`
|
|
136
|
+
*/
|
|
137
|
+
private getGA4ClientIdFromCookie;
|
|
128
138
|
private fetchSession;
|
|
129
139
|
private getLocationId;
|
|
130
140
|
private getAutoParams;
|
|
@@ -132,6 +142,7 @@ declare class CallForge {
|
|
|
132
142
|
private saveToCache;
|
|
133
143
|
private formatSession;
|
|
134
144
|
private formatApiResponse;
|
|
145
|
+
private syncGA4ClientIdIfNeeded;
|
|
135
146
|
private buildUrl;
|
|
136
147
|
}
|
|
137
148
|
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ interface CallForgeConfig {
|
|
|
8
8
|
endpoint?: string;
|
|
9
9
|
/** Optional - explicit site key for cache partitioning. Defaults to window.location.hostname */
|
|
10
10
|
siteKey?: string;
|
|
11
|
-
/** Optional - GA4 Measurement ID (e.g., "G-XXXXXXXXXX"). Enables gtag
|
|
11
|
+
/** Optional - GA4 Measurement ID (e.g., "G-XXXXXXXXXX"). Enables gtag-based client_id capture for late-loading GA. */
|
|
12
12
|
ga4MeasurementId?: string;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
@@ -121,10 +121,20 @@ declare class CallForge {
|
|
|
121
121
|
*/
|
|
122
122
|
getQueuedParams(): TrackingParams;
|
|
123
123
|
/**
|
|
124
|
-
* Capture the GA4 client ID
|
|
125
|
-
*
|
|
124
|
+
* Capture the GA4 client ID.
|
|
125
|
+
*
|
|
126
|
+
* Prefer `_ga` cookie parsing (works even when gtag is not loaded yet).
|
|
127
|
+
* If ga4MeasurementId is configured and gtag is available, use gtag as a fallback.
|
|
126
128
|
*/
|
|
127
129
|
private captureGA4ClientId;
|
|
130
|
+
private startGA4ClientIdPolling;
|
|
131
|
+
/**
|
|
132
|
+
* Extract GA4 client_id from the `_ga` cookie.
|
|
133
|
+
*
|
|
134
|
+
* Example cookie value: `GA1.1.1234567890.1234567890`
|
|
135
|
+
* Returns: `1234567890.1234567890`
|
|
136
|
+
*/
|
|
137
|
+
private getGA4ClientIdFromCookie;
|
|
128
138
|
private fetchSession;
|
|
129
139
|
private getLocationId;
|
|
130
140
|
private getAutoParams;
|
|
@@ -132,6 +142,7 @@ declare class CallForge {
|
|
|
132
142
|
private saveToCache;
|
|
133
143
|
private formatSession;
|
|
134
144
|
private formatApiResponse;
|
|
145
|
+
private syncGA4ClientIdIfNeeded;
|
|
135
146
|
private buildUrl;
|
|
136
147
|
}
|
|
137
148
|
|
package/dist/index.js
CHANGED
|
@@ -155,6 +155,7 @@ var CallForge = class _CallForge {
|
|
|
155
155
|
};
|
|
156
156
|
this.cache = new TrackingCache(config.categoryId, config.siteKey);
|
|
157
157
|
this.captureGA4ClientId();
|
|
158
|
+
this.startGA4ClientIdPolling();
|
|
158
159
|
}
|
|
159
160
|
/**
|
|
160
161
|
* Initialize the CallForge tracking client.
|
|
@@ -213,6 +214,20 @@ var CallForge = class _CallForge {
|
|
|
213
214
|
*/
|
|
214
215
|
async setParams(params) {
|
|
215
216
|
this.customParams = __spreadValues(__spreadValues({}, this.customParams), params);
|
|
217
|
+
if (params.ga4ClientId) {
|
|
218
|
+
const sync = async () => {
|
|
219
|
+
try {
|
|
220
|
+
await this.syncGA4ClientIdIfNeeded();
|
|
221
|
+
} catch (e) {
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
if (this.sessionPromise) {
|
|
225
|
+
void this.sessionPromise.then(sync).catch(() => {
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
void sync();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
216
231
|
}
|
|
217
232
|
/**
|
|
218
233
|
* Get the currently queued custom params.
|
|
@@ -221,25 +236,67 @@ var CallForge = class _CallForge {
|
|
|
221
236
|
return __spreadValues({}, this.customParams);
|
|
222
237
|
}
|
|
223
238
|
/**
|
|
224
|
-
* Capture the GA4 client ID
|
|
225
|
-
*
|
|
239
|
+
* Capture the GA4 client ID.
|
|
240
|
+
*
|
|
241
|
+
* Prefer `_ga` cookie parsing (works even when gtag is not loaded yet).
|
|
242
|
+
* If ga4MeasurementId is configured and gtag is available, use gtag as a fallback.
|
|
226
243
|
*/
|
|
227
244
|
captureGA4ClientId() {
|
|
228
|
-
if (
|
|
245
|
+
if (this.customParams.ga4ClientId) {
|
|
229
246
|
return;
|
|
230
247
|
}
|
|
231
|
-
|
|
248
|
+
const fromCookie = this.getGA4ClientIdFromCookie();
|
|
249
|
+
if (fromCookie) {
|
|
250
|
+
this.setParams({ ga4ClientId: fromCookie });
|
|
232
251
|
return;
|
|
233
252
|
}
|
|
253
|
+
if (!this.config.ga4MeasurementId) return;
|
|
254
|
+
if (typeof window === "undefined" || !window.gtag) return;
|
|
234
255
|
window.gtag("get", this.config.ga4MeasurementId, "client_id", (clientId) => {
|
|
235
256
|
if (clientId) {
|
|
236
257
|
this.setParams({ ga4ClientId: clientId });
|
|
237
258
|
}
|
|
238
259
|
});
|
|
239
260
|
}
|
|
261
|
+
startGA4ClientIdPolling() {
|
|
262
|
+
if (!this.config.ga4MeasurementId) return;
|
|
263
|
+
if (typeof window === "undefined") return;
|
|
264
|
+
if (this.customParams.ga4ClientId) return;
|
|
265
|
+
const MAX_ATTEMPTS = 20;
|
|
266
|
+
const INTERVAL_MS = 250;
|
|
267
|
+
let attempts = 0;
|
|
268
|
+
const poll = () => {
|
|
269
|
+
if (this.customParams.ga4ClientId) return;
|
|
270
|
+
this.captureGA4ClientId();
|
|
271
|
+
attempts += 1;
|
|
272
|
+
if (this.customParams.ga4ClientId) return;
|
|
273
|
+
if (attempts >= MAX_ATTEMPTS) return;
|
|
274
|
+
window.setTimeout(poll, INTERVAL_MS);
|
|
275
|
+
};
|
|
276
|
+
window.setTimeout(poll, INTERVAL_MS);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Extract GA4 client_id from the `_ga` cookie.
|
|
280
|
+
*
|
|
281
|
+
* Example cookie value: `GA1.1.1234567890.1234567890`
|
|
282
|
+
* Returns: `1234567890.1234567890`
|
|
283
|
+
*/
|
|
284
|
+
getGA4ClientIdFromCookie() {
|
|
285
|
+
if (typeof document === "undefined") return null;
|
|
286
|
+
const match = document.cookie.match(/(?:^|;\s*)_ga=([^;]+)/);
|
|
287
|
+
if (!match) return null;
|
|
288
|
+
const cookieValue = decodeURIComponent(match[1] || "");
|
|
289
|
+
const parts = cookieValue.split(".");
|
|
290
|
+
if (parts.length < 2) return null;
|
|
291
|
+
const partA = parts[parts.length - 2];
|
|
292
|
+
const partB = parts[parts.length - 1];
|
|
293
|
+
if (!/^\d+$/.test(partA) || !/^\d+$/.test(partB)) return null;
|
|
294
|
+
return `${partA}.${partB}`;
|
|
295
|
+
}
|
|
240
296
|
async fetchSession() {
|
|
241
297
|
var _a;
|
|
242
298
|
const locationId = this.getLocationId();
|
|
299
|
+
this.captureGA4ClientId();
|
|
243
300
|
if (typeof window !== "undefined" && window.__cfTracking) {
|
|
244
301
|
try {
|
|
245
302
|
const data2 = await window.__cfTracking;
|
|
@@ -254,6 +311,13 @@ var CallForge = class _CallForge {
|
|
|
254
311
|
}
|
|
255
312
|
const cached = this.cache.get(locationId);
|
|
256
313
|
if (cached) {
|
|
314
|
+
const autoParams2 = this.getAutoParams();
|
|
315
|
+
const params2 = __spreadValues(__spreadValues(__spreadValues({}, autoParams2), cached.params), this.customParams);
|
|
316
|
+
if (params2.ga4ClientId && cached.params.ga4ClientId !== params2.ga4ClientId) {
|
|
317
|
+
const data2 = await this.fetchFromApi(locationId, cached.sessionToken, params2);
|
|
318
|
+
this.saveToCache(locationId, data2, params2);
|
|
319
|
+
return this.formatApiResponse(data2);
|
|
320
|
+
}
|
|
257
321
|
return this.formatSession(cached);
|
|
258
322
|
}
|
|
259
323
|
const autoParams = this.getAutoParams();
|
|
@@ -327,6 +391,21 @@ var CallForge = class _CallForge {
|
|
|
327
391
|
location: data.location
|
|
328
392
|
};
|
|
329
393
|
}
|
|
394
|
+
async syncGA4ClientIdIfNeeded() {
|
|
395
|
+
const ga4ClientId = this.customParams.ga4ClientId;
|
|
396
|
+
if (!ga4ClientId) return;
|
|
397
|
+
const locationId = this.getLocationId();
|
|
398
|
+
const sessionToken = this.cache.getSessionToken(locationId);
|
|
399
|
+
if (!sessionToken) return;
|
|
400
|
+
const autoParams = this.getAutoParams();
|
|
401
|
+
const cachedParams = this.cache.getParams();
|
|
402
|
+
const params = __spreadValues(__spreadValues(__spreadValues({}, autoParams), cachedParams), this.customParams);
|
|
403
|
+
if (cachedParams.ga4ClientId === params.ga4ClientId) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const data = await this.fetchFromApi(locationId, sessionToken, params);
|
|
407
|
+
this.saveToCache(locationId, data, params);
|
|
408
|
+
}
|
|
330
409
|
buildUrl(locationId, sessionToken, params) {
|
|
331
410
|
const { categoryId, endpoint } = this.config;
|
|
332
411
|
const queryParams = {
|
|
@@ -371,6 +450,8 @@ var u=new URLSearchParams(location.search);
|
|
|
371
450
|
var loc=u.get('loc_physical_ms');
|
|
372
451
|
var ap=['gclid','gbraid','wbraid','msclkid','fbclid','gad_campaignid','gad_source'];
|
|
373
452
|
var p={};
|
|
453
|
+
var m=document.cookie.match(/(?:^|;\\s*)_ga=([^;]+)/);
|
|
454
|
+
if(m){try{var g=decodeURIComponent(m[1]||'');var s=g.split('.');if(s.length>=2){var a=s[s.length-2],b=s[s.length-1];if(/^\\d+$/.test(a)&&/^\\d+$/.test(b))p.ga4ClientId=a+'.'+b}}catch(e){}}
|
|
374
455
|
for(var i=0;i<ap.length;i++){var v=u.get(ap[i]);if(v)p[ap[i]]=v}
|
|
375
456
|
var site='${config.siteKey || ""}'||location.hostname||'unknown-site';
|
|
376
457
|
var key='cf_tracking_v1_'+site+'_${categoryId}';
|
package/dist/index.mjs
CHANGED
|
@@ -131,6 +131,7 @@ var CallForge = class _CallForge {
|
|
|
131
131
|
};
|
|
132
132
|
this.cache = new TrackingCache(config.categoryId, config.siteKey);
|
|
133
133
|
this.captureGA4ClientId();
|
|
134
|
+
this.startGA4ClientIdPolling();
|
|
134
135
|
}
|
|
135
136
|
/**
|
|
136
137
|
* Initialize the CallForge tracking client.
|
|
@@ -189,6 +190,20 @@ var CallForge = class _CallForge {
|
|
|
189
190
|
*/
|
|
190
191
|
async setParams(params) {
|
|
191
192
|
this.customParams = __spreadValues(__spreadValues({}, this.customParams), params);
|
|
193
|
+
if (params.ga4ClientId) {
|
|
194
|
+
const sync = async () => {
|
|
195
|
+
try {
|
|
196
|
+
await this.syncGA4ClientIdIfNeeded();
|
|
197
|
+
} catch (e) {
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
if (this.sessionPromise) {
|
|
201
|
+
void this.sessionPromise.then(sync).catch(() => {
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
204
|
+
void sync();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
192
207
|
}
|
|
193
208
|
/**
|
|
194
209
|
* Get the currently queued custom params.
|
|
@@ -197,25 +212,67 @@ var CallForge = class _CallForge {
|
|
|
197
212
|
return __spreadValues({}, this.customParams);
|
|
198
213
|
}
|
|
199
214
|
/**
|
|
200
|
-
* Capture the GA4 client ID
|
|
201
|
-
*
|
|
215
|
+
* Capture the GA4 client ID.
|
|
216
|
+
*
|
|
217
|
+
* Prefer `_ga` cookie parsing (works even when gtag is not loaded yet).
|
|
218
|
+
* If ga4MeasurementId is configured and gtag is available, use gtag as a fallback.
|
|
202
219
|
*/
|
|
203
220
|
captureGA4ClientId() {
|
|
204
|
-
if (
|
|
221
|
+
if (this.customParams.ga4ClientId) {
|
|
205
222
|
return;
|
|
206
223
|
}
|
|
207
|
-
|
|
224
|
+
const fromCookie = this.getGA4ClientIdFromCookie();
|
|
225
|
+
if (fromCookie) {
|
|
226
|
+
this.setParams({ ga4ClientId: fromCookie });
|
|
208
227
|
return;
|
|
209
228
|
}
|
|
229
|
+
if (!this.config.ga4MeasurementId) return;
|
|
230
|
+
if (typeof window === "undefined" || !window.gtag) return;
|
|
210
231
|
window.gtag("get", this.config.ga4MeasurementId, "client_id", (clientId) => {
|
|
211
232
|
if (clientId) {
|
|
212
233
|
this.setParams({ ga4ClientId: clientId });
|
|
213
234
|
}
|
|
214
235
|
});
|
|
215
236
|
}
|
|
237
|
+
startGA4ClientIdPolling() {
|
|
238
|
+
if (!this.config.ga4MeasurementId) return;
|
|
239
|
+
if (typeof window === "undefined") return;
|
|
240
|
+
if (this.customParams.ga4ClientId) return;
|
|
241
|
+
const MAX_ATTEMPTS = 20;
|
|
242
|
+
const INTERVAL_MS = 250;
|
|
243
|
+
let attempts = 0;
|
|
244
|
+
const poll = () => {
|
|
245
|
+
if (this.customParams.ga4ClientId) return;
|
|
246
|
+
this.captureGA4ClientId();
|
|
247
|
+
attempts += 1;
|
|
248
|
+
if (this.customParams.ga4ClientId) return;
|
|
249
|
+
if (attempts >= MAX_ATTEMPTS) return;
|
|
250
|
+
window.setTimeout(poll, INTERVAL_MS);
|
|
251
|
+
};
|
|
252
|
+
window.setTimeout(poll, INTERVAL_MS);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Extract GA4 client_id from the `_ga` cookie.
|
|
256
|
+
*
|
|
257
|
+
* Example cookie value: `GA1.1.1234567890.1234567890`
|
|
258
|
+
* Returns: `1234567890.1234567890`
|
|
259
|
+
*/
|
|
260
|
+
getGA4ClientIdFromCookie() {
|
|
261
|
+
if (typeof document === "undefined") return null;
|
|
262
|
+
const match = document.cookie.match(/(?:^|;\s*)_ga=([^;]+)/);
|
|
263
|
+
if (!match) return null;
|
|
264
|
+
const cookieValue = decodeURIComponent(match[1] || "");
|
|
265
|
+
const parts = cookieValue.split(".");
|
|
266
|
+
if (parts.length < 2) return null;
|
|
267
|
+
const partA = parts[parts.length - 2];
|
|
268
|
+
const partB = parts[parts.length - 1];
|
|
269
|
+
if (!/^\d+$/.test(partA) || !/^\d+$/.test(partB)) return null;
|
|
270
|
+
return `${partA}.${partB}`;
|
|
271
|
+
}
|
|
216
272
|
async fetchSession() {
|
|
217
273
|
var _a;
|
|
218
274
|
const locationId = this.getLocationId();
|
|
275
|
+
this.captureGA4ClientId();
|
|
219
276
|
if (typeof window !== "undefined" && window.__cfTracking) {
|
|
220
277
|
try {
|
|
221
278
|
const data2 = await window.__cfTracking;
|
|
@@ -230,6 +287,13 @@ var CallForge = class _CallForge {
|
|
|
230
287
|
}
|
|
231
288
|
const cached = this.cache.get(locationId);
|
|
232
289
|
if (cached) {
|
|
290
|
+
const autoParams2 = this.getAutoParams();
|
|
291
|
+
const params2 = __spreadValues(__spreadValues(__spreadValues({}, autoParams2), cached.params), this.customParams);
|
|
292
|
+
if (params2.ga4ClientId && cached.params.ga4ClientId !== params2.ga4ClientId) {
|
|
293
|
+
const data2 = await this.fetchFromApi(locationId, cached.sessionToken, params2);
|
|
294
|
+
this.saveToCache(locationId, data2, params2);
|
|
295
|
+
return this.formatApiResponse(data2);
|
|
296
|
+
}
|
|
233
297
|
return this.formatSession(cached);
|
|
234
298
|
}
|
|
235
299
|
const autoParams = this.getAutoParams();
|
|
@@ -303,6 +367,21 @@ var CallForge = class _CallForge {
|
|
|
303
367
|
location: data.location
|
|
304
368
|
};
|
|
305
369
|
}
|
|
370
|
+
async syncGA4ClientIdIfNeeded() {
|
|
371
|
+
const ga4ClientId = this.customParams.ga4ClientId;
|
|
372
|
+
if (!ga4ClientId) return;
|
|
373
|
+
const locationId = this.getLocationId();
|
|
374
|
+
const sessionToken = this.cache.getSessionToken(locationId);
|
|
375
|
+
if (!sessionToken) return;
|
|
376
|
+
const autoParams = this.getAutoParams();
|
|
377
|
+
const cachedParams = this.cache.getParams();
|
|
378
|
+
const params = __spreadValues(__spreadValues(__spreadValues({}, autoParams), cachedParams), this.customParams);
|
|
379
|
+
if (cachedParams.ga4ClientId === params.ga4ClientId) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const data = await this.fetchFromApi(locationId, sessionToken, params);
|
|
383
|
+
this.saveToCache(locationId, data, params);
|
|
384
|
+
}
|
|
306
385
|
buildUrl(locationId, sessionToken, params) {
|
|
307
386
|
const { categoryId, endpoint } = this.config;
|
|
308
387
|
const queryParams = {
|
|
@@ -347,6 +426,8 @@ var u=new URLSearchParams(location.search);
|
|
|
347
426
|
var loc=u.get('loc_physical_ms');
|
|
348
427
|
var ap=['gclid','gbraid','wbraid','msclkid','fbclid','gad_campaignid','gad_source'];
|
|
349
428
|
var p={};
|
|
429
|
+
var m=document.cookie.match(/(?:^|;\\s*)_ga=([^;]+)/);
|
|
430
|
+
if(m){try{var g=decodeURIComponent(m[1]||'');var s=g.split('.');if(s.length>=2){var a=s[s.length-2],b=s[s.length-1];if(/^\\d+$/.test(a)&&/^\\d+$/.test(b))p.ga4ClientId=a+'.'+b}}catch(e){}}
|
|
350
431
|
for(var i=0;i<ap.length;i++){var v=u.get(ap[i]);if(v)p[ap[i]]=v}
|
|
351
432
|
var site='${config.siteKey || ""}'||location.hostname||'unknown-site';
|
|
352
433
|
var key='cf_tracking_v1_'+site+'_${categoryId}';
|