@bacano/sdk 1.1.20 → 1.2.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 +4 -0
- package/STOREFRONT_FORMS.md +7 -0
- package/STOREFRONT_MARKETING.md +161 -6
- package/index.cjs +322 -86
- package/index.js +322 -86
- package/marketing/browser-adapters.d.ts +30 -0
- package/marketing/clarity.d.ts +1 -1
- package/marketing/form-interactions.d.ts +12 -0
- package/marketing/gtm.d.ts +6 -0
- package/marketing/index.d.ts +2 -0
- package/marketing/interactions.d.ts +19 -0
- package/marketing/types.d.ts +5 -2
- package/package.json +1 -1
- package/react/cta-tracking.d.ts +5 -0
- package/react/form-sections.d.ts +16 -0
- package/react/form-tracking.d.ts +11 -0
- package/react/forms.cjs +230 -93
- package/react/forms.d.ts +6 -2
- package/react/forms.js +222 -85
- package/react/marketing-provider.d.ts +2 -1
- package/react.cjs +411 -136
- package/react.d.ts +1 -0
- package/react.js +394 -119
- package/skills/bacano-web/SKILL.md +5 -0
- package/skills/bacano-web/references/forms.md +5 -0
- package/skills/bacano-web/references/interactions.md +147 -0
- package/skills/bacano-web/references/report.md +5 -0
- package/types.d.ts +4 -0
package/react.cjs
CHANGED
|
@@ -33,6 +33,7 @@ __export(react_exports, {
|
|
|
33
33
|
useAttributeList: () => useAttributeList,
|
|
34
34
|
useAvailability: () => useAvailability,
|
|
35
35
|
useBacano: () => useBacano,
|
|
36
|
+
useBacanoCta: () => useBacanoCta,
|
|
36
37
|
useBacanoState: () => useBacanoState,
|
|
37
38
|
useBrands: () => useBrands,
|
|
38
39
|
useCart: () => useCart,
|
|
@@ -4149,7 +4150,7 @@ function createCatalogModule(graphqlUrl, getHeaders, getContext, storageUrl) {
|
|
|
4149
4150
|
};
|
|
4150
4151
|
}
|
|
4151
4152
|
|
|
4152
|
-
// libs/sdk/src/react/
|
|
4153
|
+
// libs/sdk/src/react/cta-tracking.ts
|
|
4153
4154
|
var import_react2 = require("react");
|
|
4154
4155
|
|
|
4155
4156
|
// libs/sdk/src/react/context-registry.ts
|
|
@@ -4178,13 +4179,6 @@ function getOrCreateReactContext(key, defaultValue) {
|
|
|
4178
4179
|
return context;
|
|
4179
4180
|
}
|
|
4180
4181
|
|
|
4181
|
-
// libs/sdk/src/react/context.ts
|
|
4182
|
-
var BacanoReactContext = getOrCreateReactContext("bacano-client-v1", {
|
|
4183
|
-
client: null,
|
|
4184
|
-
loading: true,
|
|
4185
|
-
error: null
|
|
4186
|
-
});
|
|
4187
|
-
|
|
4188
4182
|
// libs/sdk/src/react/marketing-context.ts
|
|
4189
4183
|
var NOOP_MARKETING_RUNTIME = {
|
|
4190
4184
|
enabled: false,
|
|
@@ -4198,26 +4192,55 @@ var BacanoMarketingContext = getOrCreateReactContext(
|
|
|
4198
4192
|
NOOP_MARKETING_RUNTIME
|
|
4199
4193
|
);
|
|
4200
4194
|
|
|
4195
|
+
// libs/sdk/src/react/cta-tracking.ts
|
|
4196
|
+
function useBacanoCta(context) {
|
|
4197
|
+
const runtime = (0, import_react2.useContext)(BacanoMarketingContext);
|
|
4198
|
+
const lastClick = (0, import_react2.useRef)({ identity: "", at: -Infinity });
|
|
4199
|
+
const { ctaId, formKey, placement } = context;
|
|
4200
|
+
return (0, import_react2.useCallback)(() => {
|
|
4201
|
+
if (!runtime.enabled) return;
|
|
4202
|
+
const identity = `${ctaId}:${formKey ?? ""}:${placement ?? ""}`;
|
|
4203
|
+
const at = Date.now();
|
|
4204
|
+
if (identity === lastClick.current.identity && at - lastClick.current.at < 400)
|
|
4205
|
+
return;
|
|
4206
|
+
lastClick.current = { identity, at };
|
|
4207
|
+
try {
|
|
4208
|
+
runtime.track({ eventName: "cta_click", ctaId, formKey, placement });
|
|
4209
|
+
} catch {
|
|
4210
|
+
}
|
|
4211
|
+
}, [runtime, ctaId, formKey, placement]);
|
|
4212
|
+
}
|
|
4213
|
+
|
|
4214
|
+
// libs/sdk/src/react/hooks.ts
|
|
4215
|
+
var import_react3 = require("react");
|
|
4216
|
+
|
|
4217
|
+
// libs/sdk/src/react/context.ts
|
|
4218
|
+
var BacanoReactContext = getOrCreateReactContext("bacano-client-v1", {
|
|
4219
|
+
client: null,
|
|
4220
|
+
loading: true,
|
|
4221
|
+
error: null
|
|
4222
|
+
});
|
|
4223
|
+
|
|
4201
4224
|
// libs/sdk/src/react/hooks.ts
|
|
4202
4225
|
function useClient() {
|
|
4203
|
-
const { client, loading, error } = (0,
|
|
4226
|
+
const { client, loading, error } = (0, import_react3.useContext)(BacanoReactContext);
|
|
4204
4227
|
if (error) throw error;
|
|
4205
4228
|
if (loading || !client) throw new NotInitializedError();
|
|
4206
4229
|
return client;
|
|
4207
4230
|
}
|
|
4208
4231
|
function useSafeClient() {
|
|
4209
|
-
const { client } = (0,
|
|
4232
|
+
const { client } = (0, import_react3.useContext)(BacanoReactContext);
|
|
4210
4233
|
return client;
|
|
4211
4234
|
}
|
|
4212
4235
|
function useAsync(fetcher, deps = []) {
|
|
4213
4236
|
const client = useSafeClient();
|
|
4214
|
-
const [state, setState] = (0,
|
|
4237
|
+
const [state, setState] = (0, import_react3.useState)({
|
|
4215
4238
|
data: null,
|
|
4216
4239
|
loading: true,
|
|
4217
4240
|
error: null
|
|
4218
4241
|
});
|
|
4219
|
-
const mountedRef = (0,
|
|
4220
|
-
const fetchData = (0,
|
|
4242
|
+
const mountedRef = (0, import_react3.useRef)(true);
|
|
4243
|
+
const fetchData = (0, import_react3.useCallback)(async () => {
|
|
4221
4244
|
if (!client) return;
|
|
4222
4245
|
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
4223
4246
|
try {
|
|
@@ -4235,7 +4258,7 @@ function useAsync(fetcher, deps = []) {
|
|
|
4235
4258
|
}
|
|
4236
4259
|
}
|
|
4237
4260
|
}, [client, ...deps]);
|
|
4238
|
-
(0,
|
|
4261
|
+
(0, import_react3.useEffect)(() => {
|
|
4239
4262
|
mountedRef.current = true;
|
|
4240
4263
|
fetchData();
|
|
4241
4264
|
return () => {
|
|
@@ -4248,10 +4271,10 @@ function useBacano() {
|
|
|
4248
4271
|
return useClient();
|
|
4249
4272
|
}
|
|
4250
4273
|
function useBacanoState() {
|
|
4251
|
-
return (0,
|
|
4274
|
+
return (0, import_react3.useContext)(BacanoReactContext);
|
|
4252
4275
|
}
|
|
4253
4276
|
function useMarketing() {
|
|
4254
|
-
return (0,
|
|
4277
|
+
return (0, import_react3.useContext)(BacanoMarketingContext);
|
|
4255
4278
|
}
|
|
4256
4279
|
function useProducts(opts) {
|
|
4257
4280
|
return useAsync(
|
|
@@ -4342,10 +4365,10 @@ function useContentByTag(tag, opts) {
|
|
|
4342
4365
|
}
|
|
4343
4366
|
function useCart() {
|
|
4344
4367
|
const client = useSafeClient();
|
|
4345
|
-
const [cart, setCart] = (0,
|
|
4346
|
-
const [loading, setLoading] = (0,
|
|
4347
|
-
const [error, setError] = (0,
|
|
4348
|
-
const refreshCart = (0,
|
|
4368
|
+
const [cart, setCart] = (0, import_react3.useState)(null);
|
|
4369
|
+
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
4370
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
4371
|
+
const refreshCart = (0, import_react3.useCallback)(async () => {
|
|
4349
4372
|
if (!client) return;
|
|
4350
4373
|
setLoading(true);
|
|
4351
4374
|
try {
|
|
@@ -4358,10 +4381,10 @@ function useCart() {
|
|
|
4358
4381
|
setLoading(false);
|
|
4359
4382
|
}
|
|
4360
4383
|
}, [client]);
|
|
4361
|
-
(0,
|
|
4384
|
+
(0, import_react3.useEffect)(() => {
|
|
4362
4385
|
refreshCart();
|
|
4363
4386
|
}, [refreshCart]);
|
|
4364
|
-
const addItem = (0,
|
|
4387
|
+
const addItem = (0, import_react3.useCallback)(
|
|
4365
4388
|
async (productVariantId, quantity) => {
|
|
4366
4389
|
if (!client) throw new NotInitializedError();
|
|
4367
4390
|
const item = await client.cart.addItem(productVariantId, quantity);
|
|
@@ -4370,7 +4393,7 @@ function useCart() {
|
|
|
4370
4393
|
},
|
|
4371
4394
|
[client, refreshCart]
|
|
4372
4395
|
);
|
|
4373
|
-
const updateItem = (0,
|
|
4396
|
+
const updateItem = (0, import_react3.useCallback)(
|
|
4374
4397
|
async (cartItemId, quantity) => {
|
|
4375
4398
|
if (!client) throw new NotInitializedError();
|
|
4376
4399
|
const result = await client.cart.updateItem(cartItemId, quantity);
|
|
@@ -4379,7 +4402,7 @@ function useCart() {
|
|
|
4379
4402
|
},
|
|
4380
4403
|
[client, refreshCart]
|
|
4381
4404
|
);
|
|
4382
|
-
const removeItem = (0,
|
|
4405
|
+
const removeItem = (0, import_react3.useCallback)(
|
|
4383
4406
|
async (cartItemId) => {
|
|
4384
4407
|
if (!client) throw new NotInitializedError();
|
|
4385
4408
|
await client.cart.removeItem(cartItemId);
|
|
@@ -4387,7 +4410,7 @@ function useCart() {
|
|
|
4387
4410
|
},
|
|
4388
4411
|
[client, refreshCart]
|
|
4389
4412
|
);
|
|
4390
|
-
const clear = (0,
|
|
4413
|
+
const clear = (0, import_react3.useCallback)(async () => {
|
|
4391
4414
|
if (!client) throw new NotInitializedError();
|
|
4392
4415
|
setLoading(true);
|
|
4393
4416
|
try {
|
|
@@ -4402,7 +4425,7 @@ function useCart() {
|
|
|
4402
4425
|
setLoading(false);
|
|
4403
4426
|
}
|
|
4404
4427
|
}, [client]);
|
|
4405
|
-
const getOrCreate = (0,
|
|
4428
|
+
const getOrCreate = (0, import_react3.useCallback)(
|
|
4406
4429
|
async (contact, fulfillmentFamily) => {
|
|
4407
4430
|
if (!client) throw new NotInitializedError();
|
|
4408
4431
|
const c = await client.cart.getOrCreate(contact, fulfillmentFamily);
|
|
@@ -4411,7 +4434,7 @@ function useCart() {
|
|
|
4411
4434
|
},
|
|
4412
4435
|
[client]
|
|
4413
4436
|
);
|
|
4414
|
-
const startCheckout = (0,
|
|
4437
|
+
const startCheckout = (0, import_react3.useCallback)(
|
|
4415
4438
|
async (input) => {
|
|
4416
4439
|
if (!client) throw new NotInitializedError();
|
|
4417
4440
|
const c = await client.cart.startCheckout(input);
|
|
@@ -4435,9 +4458,9 @@ function useCart() {
|
|
|
4435
4458
|
}
|
|
4436
4459
|
function useCheckout() {
|
|
4437
4460
|
const client = useSafeClient();
|
|
4438
|
-
const [loading, setLoading] = (0,
|
|
4439
|
-
const [error, setError] = (0,
|
|
4440
|
-
const checkout = (0,
|
|
4461
|
+
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
4462
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
4463
|
+
const checkout = (0, import_react3.useCallback)(
|
|
4441
4464
|
async (input) => {
|
|
4442
4465
|
if (!client) throw new NotInitializedError();
|
|
4443
4466
|
setLoading(true);
|
|
@@ -4477,7 +4500,7 @@ function useProfile() {
|
|
|
4477
4500
|
error,
|
|
4478
4501
|
refetch
|
|
4479
4502
|
} = useAsync((client2) => client2.profile.get());
|
|
4480
|
-
const updateProfile = (0,
|
|
4503
|
+
const updateProfile = (0, import_react3.useCallback)(
|
|
4481
4504
|
async (data) => {
|
|
4482
4505
|
if (!client) throw new NotInitializedError();
|
|
4483
4506
|
const updated = await client.profile.update(data);
|
|
@@ -4490,7 +4513,7 @@ function useProfile() {
|
|
|
4490
4513
|
}
|
|
4491
4514
|
|
|
4492
4515
|
// libs/sdk/src/react/marketing-provider.tsx
|
|
4493
|
-
var
|
|
4516
|
+
var import_react5 = require("react");
|
|
4494
4517
|
|
|
4495
4518
|
// libs/sdk/src/marketing/sanitize.ts
|
|
4496
4519
|
var SENSITIVE_PARAMETER_PATTERNS = [
|
|
@@ -4530,6 +4553,9 @@ var ALLOWED_MARKETING_PARAMETERS = /* @__PURE__ */ new Set([
|
|
|
4530
4553
|
function sanitizeMarketingUrl(input, baseUrl) {
|
|
4531
4554
|
try {
|
|
4532
4555
|
const url = new URL(input, baseUrl);
|
|
4556
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return "";
|
|
4557
|
+
url.username = "";
|
|
4558
|
+
url.password = "";
|
|
4533
4559
|
const safeParameters = new URLSearchParams();
|
|
4534
4560
|
for (const [key, value] of url.searchParams.entries()) {
|
|
4535
4561
|
if (ALLOWED_MARKETING_PARAMETERS.has(key.toLowerCase()) && !SENSITIVE_PARAMETER_PATTERNS.some((pattern) => pattern.test(key))) {
|
|
@@ -4749,50 +4775,65 @@ function serializeWebsiteMarketingAttribution(attribution) {
|
|
|
4749
4775
|
};
|
|
4750
4776
|
}
|
|
4751
4777
|
|
|
4752
|
-
// libs/sdk/src/marketing/
|
|
4753
|
-
var
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4778
|
+
// libs/sdk/src/marketing/interactions.ts
|
|
4779
|
+
var WEBSITE_INTERACTION_EVENTS = [
|
|
4780
|
+
"cta_click",
|
|
4781
|
+
"form_open",
|
|
4782
|
+
"form_start",
|
|
4783
|
+
"form_step_complete",
|
|
4784
|
+
"form_submit_attempt",
|
|
4785
|
+
"form_submit_error",
|
|
4786
|
+
"form_submit_success"
|
|
4787
|
+
];
|
|
4788
|
+
function isInteractionEvent(name) {
|
|
4789
|
+
return WEBSITE_INTERACTION_EVENTS.some((candidate) => candidate === name);
|
|
4790
|
+
}
|
|
4791
|
+
function isInteractionIdentifier(value) {
|
|
4792
|
+
return typeof value === "string" && /^[a-z][a-z0-9_-]{0,63}$/.test(value);
|
|
4793
|
+
}
|
|
4794
|
+
function isBrowserMarketingEvent(name) {
|
|
4795
|
+
return isInteractionEvent(name) || [
|
|
4796
|
+
"page_view",
|
|
4797
|
+
"search",
|
|
4798
|
+
"view_item_list",
|
|
4799
|
+
"select_item",
|
|
4800
|
+
"view_item",
|
|
4801
|
+
"add_to_cart",
|
|
4802
|
+
"remove_from_cart",
|
|
4803
|
+
"view_cart",
|
|
4804
|
+
"begin_checkout",
|
|
4805
|
+
"add_shipping_info",
|
|
4806
|
+
"add_payment_info",
|
|
4807
|
+
"contact"
|
|
4808
|
+
].includes(name);
|
|
4809
|
+
}
|
|
4810
|
+
function interactionParameters(event) {
|
|
4811
|
+
if (!isInteractionEvent(event.eventName)) return {};
|
|
4812
|
+
if (event.eventName === "cta_click" ? !isInteractionIdentifier(event.ctaId) : !isInteractionIdentifier(event.formKey))
|
|
4813
|
+
return null;
|
|
4814
|
+
if (event.eventName === "form_step_complete" && !isInteractionIdentifier(event.stepKey))
|
|
4815
|
+
return null;
|
|
4816
|
+
if (event.eventName === "form_submit_error" && !["validation", "network", "rejected", "unavailable"].includes(
|
|
4817
|
+
event.errorCategory ?? ""
|
|
4818
|
+
))
|
|
4819
|
+
return null;
|
|
4820
|
+
const params = {};
|
|
4821
|
+
for (const [key, value] of Object.entries({
|
|
4822
|
+
form_key: event.formKey,
|
|
4823
|
+
cta_id: event.ctaId,
|
|
4824
|
+
placement: event.placement,
|
|
4825
|
+
step_key: event.stepKey
|
|
4826
|
+
})) {
|
|
4827
|
+
if (value === void 0) continue;
|
|
4828
|
+
if (!isInteractionIdentifier(value)) return null;
|
|
4829
|
+
params[key] = value;
|
|
4766
4830
|
}
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
if (typeof document === "undefined") return;
|
|
4771
|
-
const id = `bacano-clarity-${projectId}`;
|
|
4772
|
-
if (document.getElementById(id)) return;
|
|
4773
|
-
const script = document.createElement("script");
|
|
4774
|
-
script.id = id;
|
|
4775
|
-
script.async = true;
|
|
4776
|
-
script.src = `https://www.clarity.ms/tag/${encodeURIComponent(projectId)}`;
|
|
4777
|
-
script.referrerPolicy = "strict-origin-when-cross-origin";
|
|
4778
|
-
document.head.appendChild(script);
|
|
4779
|
-
}
|
|
4780
|
-
function sendClarityEvent(eventName) {
|
|
4781
|
-
clarityWindow()?.clarity?.("event", eventName);
|
|
4831
|
+
if (event.eventName === "form_submit_error" && event.errorCategory)
|
|
4832
|
+
params.error_category = event.errorCategory;
|
|
4833
|
+
return params;
|
|
4782
4834
|
}
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
function matchesCanonicalMarketingHost(canonicalDomain, currentHostname) {
|
|
4786
|
-
if (canonicalDomain === void 0) return true;
|
|
4787
|
-
if (!canonicalDomain?.trim()) return false;
|
|
4788
|
-
try {
|
|
4789
|
-
const configuredHost = new URL(
|
|
4790
|
-
canonicalDomain.includes("://") ? canonicalDomain : `https://${canonicalDomain}`
|
|
4791
|
-
).hostname.toLowerCase();
|
|
4792
|
-
return currentHostname.toLowerCase() === configuredHost;
|
|
4793
|
-
} catch {
|
|
4794
|
-
return false;
|
|
4795
|
-
}
|
|
4835
|
+
function newMarketingEventId() {
|
|
4836
|
+
return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `evt_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
4796
4837
|
}
|
|
4797
4838
|
|
|
4798
4839
|
// libs/sdk/src/marketing/ga4.ts
|
|
@@ -4819,19 +4860,20 @@ var WEBSITE_MARKETING_CONTACT_PLACEMENTS = [
|
|
|
4819
4860
|
"contact_page"
|
|
4820
4861
|
];
|
|
4821
4862
|
|
|
4822
|
-
// libs/sdk/src/marketing/
|
|
4863
|
+
// libs/sdk/src/marketing/browser-adapters.ts
|
|
4823
4864
|
var initializedGa4Destinations = /* @__PURE__ */ new Set();
|
|
4824
4865
|
var initializedMetaDestinations = /* @__PURE__ */ new Set();
|
|
4825
4866
|
function marketingWindow() {
|
|
4826
4867
|
return typeof window === "undefined" ? null : window;
|
|
4827
4868
|
}
|
|
4828
|
-
function loadScriptOnce(id, source) {
|
|
4869
|
+
function loadScriptOnce(id, source, onError) {
|
|
4829
4870
|
if (typeof document === "undefined" || document.getElementById(id)) return;
|
|
4830
4871
|
const script = document.createElement("script");
|
|
4831
4872
|
script.id = id;
|
|
4832
4873
|
script.async = true;
|
|
4833
4874
|
script.src = source;
|
|
4834
4875
|
script.referrerPolicy = "strict-origin-when-cross-origin";
|
|
4876
|
+
script.onerror = () => onError?.();
|
|
4835
4877
|
document.head.appendChild(script);
|
|
4836
4878
|
}
|
|
4837
4879
|
function prepareGa4(measurementId) {
|
|
@@ -4846,10 +4888,11 @@ function prepareGa4(measurementId) {
|
|
|
4846
4888
|
target.gtag("config", measurementId, { send_page_view: false });
|
|
4847
4889
|
initializedGa4Destinations.add(measurementId);
|
|
4848
4890
|
}
|
|
4849
|
-
function loadGa4Script(measurementId) {
|
|
4891
|
+
function loadGa4Script(measurementId, onError) {
|
|
4850
4892
|
loadScriptOnce(
|
|
4851
4893
|
`bacano-ga4-${measurementId}`,
|
|
4852
|
-
`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}
|
|
4894
|
+
`https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(measurementId)}`,
|
|
4895
|
+
onError
|
|
4853
4896
|
);
|
|
4854
4897
|
}
|
|
4855
4898
|
function captureGa4ClientId(measurementId, websiteId, diagnostic) {
|
|
@@ -4897,10 +4940,11 @@ function prepareMeta(pixelId) {
|
|
|
4897
4940
|
target.fbq("init", pixelId);
|
|
4898
4941
|
initializedMetaDestinations.add(pixelId);
|
|
4899
4942
|
}
|
|
4900
|
-
function loadMetaScript() {
|
|
4943
|
+
function loadMetaScript(onError) {
|
|
4901
4944
|
loadScriptOnce(
|
|
4902
4945
|
"bacano-meta-pixel",
|
|
4903
|
-
"https://connect.facebook.net/en_US/fbevents.js"
|
|
4946
|
+
"https://connect.facebook.net/en_US/fbevents.js",
|
|
4947
|
+
onError
|
|
4904
4948
|
);
|
|
4905
4949
|
}
|
|
4906
4950
|
function scheduleScriptLoad(load, strategy) {
|
|
@@ -4964,10 +5008,12 @@ function contactPlacementFor(event) {
|
|
|
4964
5008
|
}
|
|
4965
5009
|
return placement;
|
|
4966
5010
|
}
|
|
4967
|
-
function sendGa4(event, diagnosticMode) {
|
|
5011
|
+
function sendGa4(event, diagnosticMode, measurementId) {
|
|
4968
5012
|
const target = marketingWindow();
|
|
4969
5013
|
const contactPlacement = contactPlacementFor(event);
|
|
4970
5014
|
target?.gtag?.("event", event.eventName, {
|
|
5015
|
+
send_to: measurementId,
|
|
5016
|
+
...interactionParameters(event),
|
|
4971
5017
|
currency: event.currency,
|
|
4972
5018
|
value: event.value,
|
|
4973
5019
|
search_term: event.searchTerm,
|
|
@@ -4984,15 +5030,17 @@ function sendGa4(event, diagnosticMode) {
|
|
|
4984
5030
|
debug_mode: diagnosticMode ? true : void 0
|
|
4985
5031
|
});
|
|
4986
5032
|
}
|
|
4987
|
-
function sendMeta(event) {
|
|
5033
|
+
function sendMeta(event, pixelId) {
|
|
4988
5034
|
const target = marketingWindow();
|
|
4989
5035
|
const eventName = metaEventName(event.eventName);
|
|
4990
5036
|
const isStandard = eventName !== event.eventName;
|
|
4991
5037
|
const contactPlacement = contactPlacementFor(event);
|
|
4992
5038
|
target?.fbq?.(
|
|
4993
|
-
isStandard ? "
|
|
5039
|
+
isStandard ? "trackSingle" : "trackSingleCustom",
|
|
5040
|
+
pixelId,
|
|
4994
5041
|
eventName,
|
|
4995
5042
|
{
|
|
5043
|
+
...interactionParameters(event),
|
|
4996
5044
|
currency: event.currency,
|
|
4997
5045
|
value: event.value,
|
|
4998
5046
|
search_string: event.searchTerm,
|
|
@@ -5009,40 +5057,192 @@ function sendMeta(event) {
|
|
|
5009
5057
|
{ eventID: event.eventId }
|
|
5010
5058
|
);
|
|
5011
5059
|
}
|
|
5012
|
-
|
|
5013
|
-
|
|
5060
|
+
|
|
5061
|
+
// libs/sdk/src/marketing/clarity.ts
|
|
5062
|
+
var initializedDestinations = /* @__PURE__ */ new Set();
|
|
5063
|
+
function clarityWindow() {
|
|
5064
|
+
return typeof window === "undefined" ? null : window;
|
|
5065
|
+
}
|
|
5066
|
+
function prepareClarity(projectId) {
|
|
5067
|
+
const target = clarityWindow();
|
|
5068
|
+
if (!target || initializedDestinations.has(projectId)) return;
|
|
5069
|
+
if (!target.clarity) {
|
|
5070
|
+
const clarity = function() {
|
|
5071
|
+
clarity.q ??= [];
|
|
5072
|
+
clarity.q.push(arguments);
|
|
5073
|
+
};
|
|
5074
|
+
target.clarity = clarity;
|
|
5075
|
+
}
|
|
5076
|
+
initializedDestinations.add(projectId);
|
|
5077
|
+
}
|
|
5078
|
+
function loadClarityScript(projectId, onError) {
|
|
5079
|
+
if (typeof document === "undefined") return;
|
|
5080
|
+
const id = `bacano-clarity-${projectId}`;
|
|
5081
|
+
if (document.getElementById(id)) return;
|
|
5082
|
+
const script = document.createElement("script");
|
|
5083
|
+
script.id = id;
|
|
5084
|
+
script.async = true;
|
|
5085
|
+
script.src = `https://www.clarity.ms/tag/${encodeURIComponent(projectId)}`;
|
|
5086
|
+
script.referrerPolicy = "strict-origin-when-cross-origin";
|
|
5087
|
+
script.onerror = () => onError?.();
|
|
5088
|
+
document.head.appendChild(script);
|
|
5089
|
+
}
|
|
5090
|
+
function sendClarityEvent(eventName) {
|
|
5091
|
+
clarityWindow()?.clarity?.("event", eventName);
|
|
5092
|
+
}
|
|
5093
|
+
|
|
5094
|
+
// libs/sdk/src/marketing/domain.ts
|
|
5095
|
+
function matchesCanonicalMarketingHost(canonicalDomain, currentHostname) {
|
|
5096
|
+
if (canonicalDomain === void 0) return true;
|
|
5097
|
+
if (!canonicalDomain?.trim()) return false;
|
|
5098
|
+
try {
|
|
5099
|
+
const configuredHost = new URL(
|
|
5100
|
+
canonicalDomain.includes("://") ? canonicalDomain : `https://${canonicalDomain}`
|
|
5101
|
+
).hostname.toLowerCase();
|
|
5102
|
+
return currentHostname.toLowerCase() === configuredHost;
|
|
5103
|
+
} catch {
|
|
5104
|
+
return false;
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5107
|
+
|
|
5108
|
+
// libs/sdk/src/marketing/gtm.ts
|
|
5109
|
+
var CONTAINER_ID = /^GTM-[A-Z0-9]{4,32}$/;
|
|
5110
|
+
var preparedQueues = /* @__PURE__ */ new WeakMap();
|
|
5111
|
+
function prepareGtm(containerId) {
|
|
5112
|
+
const target = marketingWindow();
|
|
5113
|
+
if (!target || !CONTAINER_ID.test(containerId)) return;
|
|
5114
|
+
target.dataLayer ??= [];
|
|
5115
|
+
const containers = preparedQueues.get(target.dataLayer) ?? /* @__PURE__ */ new Set();
|
|
5116
|
+
if (containers.has(containerId)) return;
|
|
5117
|
+
target.dataLayer.push({ "gtm.start": Date.now(), event: "gtm.js" });
|
|
5118
|
+
containers.add(containerId);
|
|
5119
|
+
preparedQueues.set(target.dataLayer, containers);
|
|
5014
5120
|
}
|
|
5121
|
+
function loadGtmScript(containerId, onError) {
|
|
5122
|
+
const target = marketingWindow();
|
|
5123
|
+
if (!target || typeof document === "undefined" || !CONTAINER_ID.test(containerId))
|
|
5124
|
+
return;
|
|
5125
|
+
const id = `bacano-gtm-${containerId}`;
|
|
5126
|
+
if (document.getElementById(id)) return;
|
|
5127
|
+
prepareGtm(containerId);
|
|
5128
|
+
const script = document.createElement("script");
|
|
5129
|
+
script.id = id;
|
|
5130
|
+
script.async = true;
|
|
5131
|
+
script.src = `https://www.googletagmanager.com/gtm.js?id=${encodeURIComponent(containerId)}`;
|
|
5132
|
+
script.referrerPolicy = "strict-origin-when-cross-origin";
|
|
5133
|
+
script.onerror = () => onError();
|
|
5134
|
+
document.head.appendChild(script);
|
|
5135
|
+
}
|
|
5136
|
+
function sendGtm(event) {
|
|
5137
|
+
const target = marketingWindow();
|
|
5138
|
+
if (!target?.dataLayer) return;
|
|
5139
|
+
target.dataLayer.push({ bacano: null });
|
|
5140
|
+
target.dataLayer.push({
|
|
5141
|
+
event: `bacano_${event.eventName}`,
|
|
5142
|
+
bacano: {
|
|
5143
|
+
schema_version: event.schemaVersion,
|
|
5144
|
+
event_name: event.eventName,
|
|
5145
|
+
event_id: event.eventId,
|
|
5146
|
+
...interactionParameters(event),
|
|
5147
|
+
page_location: event.pageLocation,
|
|
5148
|
+
currency: event.currency,
|
|
5149
|
+
value: event.value,
|
|
5150
|
+
items: mapGa4Items(event.items),
|
|
5151
|
+
item_list_id: event.itemListId,
|
|
5152
|
+
item_list_name: event.itemListName,
|
|
5153
|
+
shipping_tier: event.shippingTier,
|
|
5154
|
+
payment_type: event.paymentType,
|
|
5155
|
+
method: event.contactMethod,
|
|
5156
|
+
contact_placement: event.eventName === "contact" && WEBSITE_MARKETING_CONTACT_PLACEMENTS.some(
|
|
5157
|
+
(value) => value === event.contactPlacement
|
|
5158
|
+
) ? event.contactPlacement : void 0
|
|
5159
|
+
}
|
|
5160
|
+
});
|
|
5161
|
+
}
|
|
5162
|
+
|
|
5163
|
+
// libs/sdk/src/marketing/runtime.ts
|
|
5015
5164
|
function createWebsiteMarketingRuntime(options) {
|
|
5016
5165
|
let destroyed = false;
|
|
5166
|
+
const dispatched = /* @__PURE__ */ new Set();
|
|
5167
|
+
const observer = options.diagnostic;
|
|
5168
|
+
const diagnostic = (value) => {
|
|
5169
|
+
try {
|
|
5170
|
+
observer?.(value);
|
|
5171
|
+
} catch {
|
|
5172
|
+
}
|
|
5173
|
+
};
|
|
5174
|
+
options = { ...options, diagnostic };
|
|
5017
5175
|
let cancelScheduledLoad = () => void 0;
|
|
5018
5176
|
const target = marketingWindow();
|
|
5019
|
-
const enabled = options.config.enabled && Boolean(
|
|
5177
|
+
const enabled = options.config.enabled && options.measurementAllowed !== false && Boolean(
|
|
5020
5178
|
target && matchesCanonicalMarketingHost(
|
|
5021
5179
|
options.canonicalDomain,
|
|
5022
5180
|
target.location.hostname
|
|
5023
5181
|
)
|
|
5024
5182
|
) && Boolean(
|
|
5025
|
-
options.config.destinations.ga4 || options.config.destinations.meta || options.config.destinations.clarity
|
|
5183
|
+
options.config.destinations.ga4 || options.config.destinations.meta || options.config.destinations.clarity || options.config.destinations.gtm
|
|
5026
5184
|
);
|
|
5185
|
+
if (!enabled)
|
|
5186
|
+
diagnostic({
|
|
5187
|
+
level: "debug",
|
|
5188
|
+
code: !options.config.enabled ? "MARKETING_DISABLED" : options.measurementAllowed === false ? "MEASUREMENT_NOT_ALLOWED" : !target ? "SERVER_RENDER" : !matchesCanonicalMarketingHost(
|
|
5189
|
+
options.canonicalDomain,
|
|
5190
|
+
target.location.hostname
|
|
5191
|
+
) ? "DOMAIN_NOT_ALLOWED" : "PROVIDER_NOT_CONFIGURED",
|
|
5192
|
+
message: "Measurement is inactive; no events are emitted"
|
|
5193
|
+
});
|
|
5027
5194
|
if (enabled) {
|
|
5195
|
+
const guard = (provider, action) => {
|
|
5196
|
+
try {
|
|
5197
|
+
action();
|
|
5198
|
+
} catch {
|
|
5199
|
+
diagnostic({
|
|
5200
|
+
level: "warning",
|
|
5201
|
+
code: "RUNTIME_INITIALIZATION_FAILED",
|
|
5202
|
+
message: `${provider}: initialization failed`
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
};
|
|
5206
|
+
const scriptError = (provider) => () => diagnostic({
|
|
5207
|
+
level: "warning",
|
|
5208
|
+
code: "SCRIPT_LOAD_FAILED",
|
|
5209
|
+
message: `${provider}: script could not load (network, CSP or blocker); external reception is unverified`
|
|
5210
|
+
});
|
|
5028
5211
|
try {
|
|
5029
5212
|
if (options.config.destinations.ga4) {
|
|
5030
|
-
|
|
5213
|
+
const { measurementId } = options.config.destinations.ga4;
|
|
5214
|
+
guard("GA4", () => prepareGa4(measurementId));
|
|
5031
5215
|
}
|
|
5032
5216
|
if (options.config.destinations.meta) {
|
|
5033
|
-
|
|
5217
|
+
const { pixelId } = options.config.destinations.meta;
|
|
5218
|
+
guard("Meta", () => prepareMeta(pixelId));
|
|
5034
5219
|
}
|
|
5035
5220
|
if (options.config.destinations.clarity) {
|
|
5036
|
-
|
|
5221
|
+
const { projectId } = options.config.destinations.clarity;
|
|
5222
|
+
guard("Clarity", () => prepareClarity(projectId));
|
|
5223
|
+
}
|
|
5224
|
+
if (options.config.destinations.gtm) {
|
|
5225
|
+
const { containerId } = options.config.destinations.gtm;
|
|
5226
|
+
guard("GTM", () => prepareGtm(containerId));
|
|
5037
5227
|
}
|
|
5038
5228
|
cancelScheduledLoad = scheduleScriptLoad(() => {
|
|
5039
5229
|
if (destroyed) return;
|
|
5040
5230
|
if (options.config.destinations.ga4) {
|
|
5041
|
-
|
|
5231
|
+
const { measurementId } = options.config.destinations.ga4;
|
|
5232
|
+
guard("GA4", () => loadGa4Script(measurementId, scriptError("GA4")));
|
|
5042
5233
|
}
|
|
5043
|
-
if (options.config.destinations.meta)
|
|
5234
|
+
if (options.config.destinations.meta)
|
|
5235
|
+
guard("Meta", () => loadMetaScript(scriptError("Meta")));
|
|
5044
5236
|
if (options.config.destinations.clarity) {
|
|
5045
|
-
|
|
5237
|
+
const { projectId } = options.config.destinations.clarity;
|
|
5238
|
+
guard(
|
|
5239
|
+
"Clarity",
|
|
5240
|
+
() => loadClarityScript(projectId, scriptError("Clarity"))
|
|
5241
|
+
);
|
|
5242
|
+
}
|
|
5243
|
+
if (options.config.destinations.gtm) {
|
|
5244
|
+
const { containerId } = options.config.destinations.gtm;
|
|
5245
|
+
guard("GTM", () => loadGtmScript(containerId, scriptError("GTM")));
|
|
5046
5246
|
}
|
|
5047
5247
|
}, options.scriptLoadStrategy);
|
|
5048
5248
|
captureWebsiteMarketingAttribution(
|
|
@@ -5064,11 +5264,11 @@ function createWebsiteMarketingRuntime(options) {
|
|
|
5064
5264
|
if (options.config.destinations.meta) {
|
|
5065
5265
|
refreshWebsiteMarketingMetaContext(options.websiteId);
|
|
5066
5266
|
}
|
|
5067
|
-
} catch
|
|
5267
|
+
} catch {
|
|
5068
5268
|
options.diagnostic?.({
|
|
5069
5269
|
level: "warning",
|
|
5070
5270
|
code: "RUNTIME_INITIALIZATION_FAILED",
|
|
5071
|
-
message:
|
|
5271
|
+
message: "Marketing initialization failed; external reception is unverified"
|
|
5072
5272
|
});
|
|
5073
5273
|
}
|
|
5074
5274
|
}
|
|
@@ -5076,41 +5276,99 @@ function createWebsiteMarketingRuntime(options) {
|
|
|
5076
5276
|
enabled,
|
|
5077
5277
|
track(input) {
|
|
5078
5278
|
if (!enabled || destroyed) return;
|
|
5279
|
+
if (!isBrowserMarketingEvent(input.eventName)) {
|
|
5280
|
+
diagnostic({
|
|
5281
|
+
level: "warning",
|
|
5282
|
+
code: "INVALID_EVENT",
|
|
5283
|
+
message: "Unknown or server-owned event rejected"
|
|
5284
|
+
});
|
|
5285
|
+
return;
|
|
5286
|
+
}
|
|
5287
|
+
try {
|
|
5288
|
+
captureWebsiteMarketingAttribution(
|
|
5289
|
+
options.websiteId,
|
|
5290
|
+
options.config.attributionWindowDays
|
|
5291
|
+
);
|
|
5292
|
+
} catch {
|
|
5293
|
+
}
|
|
5079
5294
|
const event = {
|
|
5080
5295
|
...input,
|
|
5081
5296
|
schemaVersion: 1,
|
|
5082
|
-
eventId: input.eventId ??
|
|
5297
|
+
eventId: input.eventId ?? newMarketingEventId(),
|
|
5083
5298
|
occurredAt: input.occurredAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
5084
5299
|
currency: input.currency ?? options.config.currencyCode,
|
|
5085
5300
|
pageLocation: sanitizeMarketingUrl(
|
|
5086
5301
|
input.pageLocation ?? (typeof window === "undefined" ? "" : window.location.href)
|
|
5087
5302
|
)
|
|
5088
5303
|
};
|
|
5089
|
-
|
|
5090
|
-
if (
|
|
5091
|
-
|
|
5304
|
+
if (isInteractionEvent(event.eventName)) {
|
|
5305
|
+
if (!interactionParameters(event) || !/^[a-zA-Z0-9_-]{1,100}$/.test(event.eventId)) {
|
|
5306
|
+
diagnostic({
|
|
5307
|
+
level: "warning",
|
|
5308
|
+
code: "INVALID_INTERACTION",
|
|
5309
|
+
message: "Interaction rejected by the public contract",
|
|
5310
|
+
eventName: event.eventName
|
|
5311
|
+
});
|
|
5312
|
+
return;
|
|
5092
5313
|
}
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5314
|
+
for (const key of [
|
|
5315
|
+
"currency",
|
|
5316
|
+
"value",
|
|
5317
|
+
"searchTerm",
|
|
5318
|
+
"itemListId",
|
|
5319
|
+
"itemListName",
|
|
5320
|
+
"shippingTier",
|
|
5321
|
+
"paymentType",
|
|
5322
|
+
"contactMethod",
|
|
5323
|
+
"contactPlacement",
|
|
5324
|
+
"items",
|
|
5325
|
+
"pageTitle"
|
|
5326
|
+
])
|
|
5327
|
+
delete event[key];
|
|
5328
|
+
}
|
|
5329
|
+
const identity = `${event.eventName}:${event.eventId}`;
|
|
5330
|
+
if (dispatched.has(identity)) return;
|
|
5331
|
+
dispatched.add(identity);
|
|
5332
|
+
const oldest = dispatched.values().next().value;
|
|
5333
|
+
if (dispatched.size > 1e3 && oldest) dispatched.delete(oldest);
|
|
5334
|
+
const dispatch = (provider, send) => {
|
|
5335
|
+
try {
|
|
5336
|
+
send();
|
|
5337
|
+
diagnostic({
|
|
5338
|
+
level: "debug",
|
|
5339
|
+
code: "EVENT_DISPATCHED",
|
|
5340
|
+
message: `${provider}: passed to adapter; external reception is unverified`,
|
|
5341
|
+
eventName: event.eventName
|
|
5342
|
+
});
|
|
5343
|
+
} catch {
|
|
5344
|
+
diagnostic({
|
|
5345
|
+
level: "warning",
|
|
5346
|
+
code: "EVENT_DISPATCH_FAILED",
|
|
5347
|
+
message: `${provider}: adapter failed`,
|
|
5348
|
+
eventName: event.eventName
|
|
5349
|
+
});
|
|
5096
5350
|
}
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5351
|
+
};
|
|
5352
|
+
if (options.config.destinations.ga4) {
|
|
5353
|
+
const ga4 = options.config.destinations.ga4;
|
|
5354
|
+
dispatch(
|
|
5355
|
+
"GA4",
|
|
5356
|
+
() => sendGa4(event, ga4.diagnosticMode, ga4.measurementId)
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5359
|
+
if (options.config.destinations.meta) {
|
|
5360
|
+
const meta = options.config.destinations.meta;
|
|
5361
|
+
dispatch("Meta", () => sendMeta(event, meta.pixelId));
|
|
5362
|
+
}
|
|
5363
|
+
if (options.config.destinations.clarity) {
|
|
5364
|
+
dispatch("Clarity", () => sendClarityEvent(event.eventName));
|
|
5365
|
+
}
|
|
5366
|
+
if (options.config.destinations.gtm && /^GTM-[A-Z0-9]{4,32}$/.test(options.config.destinations.gtm.containerId)) {
|
|
5367
|
+
dispatch("GTM", () => sendGtm(event));
|
|
5110
5368
|
}
|
|
5111
5369
|
},
|
|
5112
5370
|
captureAttribution() {
|
|
5113
|
-
if (!enabled) return null;
|
|
5371
|
+
if (!enabled || destroyed) return null;
|
|
5114
5372
|
captureWebsiteMarketingAttribution(
|
|
5115
5373
|
options.websiteId,
|
|
5116
5374
|
options.config.attributionWindowDays
|
|
@@ -5121,7 +5379,7 @@ function createWebsiteMarketingRuntime(options) {
|
|
|
5121
5379
|
return getWebsiteMarketingAttribution(options.websiteId);
|
|
5122
5380
|
},
|
|
5123
5381
|
getAttribution() {
|
|
5124
|
-
if (!enabled) return null;
|
|
5382
|
+
if (!enabled || destroyed) return null;
|
|
5125
5383
|
if (options.config.destinations.meta) {
|
|
5126
5384
|
refreshWebsiteMarketingMetaContext(options.websiteId);
|
|
5127
5385
|
}
|
|
@@ -5135,7 +5393,7 @@ function createWebsiteMarketingRuntime(options) {
|
|
|
5135
5393
|
}
|
|
5136
5394
|
|
|
5137
5395
|
// libs/sdk/src/react/preview/context.ts
|
|
5138
|
-
var
|
|
5396
|
+
var import_react4 = require("react");
|
|
5139
5397
|
var BacanoPreviewModeContext = getOrCreateReactContext(
|
|
5140
5398
|
"bacano-preview-mode-v1",
|
|
5141
5399
|
false
|
|
@@ -5151,15 +5409,24 @@ function BacanoMarketingProvider({
|
|
|
5151
5409
|
publicConfig,
|
|
5152
5410
|
children,
|
|
5153
5411
|
scriptLoadStrategy,
|
|
5154
|
-
diagnostic
|
|
5412
|
+
diagnostic,
|
|
5413
|
+
measurementAllowed
|
|
5155
5414
|
}) {
|
|
5156
|
-
const isPreview = (0,
|
|
5157
|
-
const [runtime, setRuntime] = (0,
|
|
5415
|
+
const isPreview = (0, import_react5.useContext)(BacanoPreviewModeContext);
|
|
5416
|
+
const [runtime, setRuntime] = (0, import_react5.useState)(
|
|
5158
5417
|
NOOP_MARKETING_RUNTIME
|
|
5159
5418
|
);
|
|
5160
|
-
(0,
|
|
5419
|
+
(0, import_react5.useEffect)(() => {
|
|
5161
5420
|
if (isPreview || !publicConfig) {
|
|
5162
5421
|
setRuntime(NOOP_MARKETING_RUNTIME);
|
|
5422
|
+
try {
|
|
5423
|
+
diagnostic?.({
|
|
5424
|
+
level: "debug",
|
|
5425
|
+
code: isPreview ? "PREVIEW_DISABLED" : "PUBLIC_CONFIG_UNAVAILABLE",
|
|
5426
|
+
message: "Measurement is inactive"
|
|
5427
|
+
});
|
|
5428
|
+
} catch {
|
|
5429
|
+
}
|
|
5163
5430
|
return;
|
|
5164
5431
|
}
|
|
5165
5432
|
const next = createWebsiteMarketingRuntime({
|
|
@@ -5167,22 +5434,29 @@ function BacanoMarketingProvider({
|
|
|
5167
5434
|
config: publicConfig.marketing,
|
|
5168
5435
|
canonicalDomain: publicConfig.domain,
|
|
5169
5436
|
scriptLoadStrategy,
|
|
5170
|
-
diagnostic
|
|
5437
|
+
diagnostic,
|
|
5438
|
+
measurementAllowed
|
|
5171
5439
|
});
|
|
5172
5440
|
setRuntime(next);
|
|
5173
5441
|
return () => next.destroy();
|
|
5174
|
-
}, [
|
|
5442
|
+
}, [
|
|
5443
|
+
diagnostic,
|
|
5444
|
+
isPreview,
|
|
5445
|
+
publicConfig,
|
|
5446
|
+
scriptLoadStrategy,
|
|
5447
|
+
measurementAllowed
|
|
5448
|
+
]);
|
|
5175
5449
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5176
5450
|
BacanoMarketingContext.Provider,
|
|
5177
5451
|
{
|
|
5178
|
-
value: isPreview ? NOOP_MARKETING_RUNTIME : runtime,
|
|
5452
|
+
value: isPreview || measurementAllowed === false ? NOOP_MARKETING_RUNTIME : runtime,
|
|
5179
5453
|
children
|
|
5180
5454
|
}
|
|
5181
5455
|
);
|
|
5182
5456
|
}
|
|
5183
5457
|
|
|
5184
5458
|
// libs/sdk/src/react/provider.tsx
|
|
5185
|
-
var
|
|
5459
|
+
var import_react6 = require("react");
|
|
5186
5460
|
|
|
5187
5461
|
// libs/sdk/src/modules/auth.ts
|
|
5188
5462
|
function createAuthHeaders(accessToken) {
|
|
@@ -5366,7 +5640,8 @@ async function getWebsitePublicConfig(options) {
|
|
|
5366
5640
|
pixelId: marketing.destinations.meta.pixel_id,
|
|
5367
5641
|
diagnosticMode: marketing.destinations.meta.diagnostic_mode ?? false
|
|
5368
5642
|
} : null,
|
|
5369
|
-
clarity: marketing.destinations.clarity ? { projectId: marketing.destinations.clarity.project_id } : null
|
|
5643
|
+
clarity: marketing.destinations.clarity ? { projectId: marketing.destinations.clarity.project_id } : null,
|
|
5644
|
+
...marketing.destinations.gtm ? { gtm: { containerId: marketing.destinations.gtm.container_id } } : {}
|
|
5370
5645
|
}
|
|
5371
5646
|
},
|
|
5372
5647
|
legal: {
|
|
@@ -7293,14 +7568,14 @@ function BacanoProvider({
|
|
|
7293
7568
|
config,
|
|
7294
7569
|
children
|
|
7295
7570
|
}) {
|
|
7296
|
-
const getAccessTokenRef = (0,
|
|
7571
|
+
const getAccessTokenRef = (0, import_react6.useRef)(config.getAccessToken);
|
|
7297
7572
|
getAccessTokenRef.current = config.getAccessToken;
|
|
7298
|
-
const [state, setState] = (0,
|
|
7573
|
+
const [state, setState] = (0, import_react6.useState)({
|
|
7299
7574
|
client: null,
|
|
7300
7575
|
loading: true,
|
|
7301
7576
|
error: null
|
|
7302
7577
|
});
|
|
7303
|
-
(0,
|
|
7578
|
+
(0, import_react6.useEffect)(() => {
|
|
7304
7579
|
let cancelled = false;
|
|
7305
7580
|
const client = createBacanoClient({
|
|
7306
7581
|
...config,
|
|
@@ -7334,7 +7609,7 @@ function BacanoProvider({
|
|
|
7334
7609
|
}
|
|
7335
7610
|
|
|
7336
7611
|
// libs/sdk/src/react/website-gate.tsx
|
|
7337
|
-
var
|
|
7612
|
+
var import_react7 = require("react");
|
|
7338
7613
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
7339
7614
|
var PREVIEW_HASH_KEY = "bacano-preview";
|
|
7340
7615
|
function previewStorageKey(websiteSlug) {
|
|
@@ -7453,11 +7728,11 @@ function BacanoWebsiteGate({
|
|
|
7453
7728
|
loadingFallback = null,
|
|
7454
7729
|
constructionFallback
|
|
7455
7730
|
}) {
|
|
7456
|
-
const [publicConfig, setPublicConfig] = (0,
|
|
7457
|
-
const [isLoading, setIsLoading] = (0,
|
|
7458
|
-
const [failedOpen, setFailedOpen] = (0,
|
|
7731
|
+
const [publicConfig, setPublicConfig] = (0, import_react7.useState)(initialConfig);
|
|
7732
|
+
const [isLoading, setIsLoading] = (0, import_react7.useState)(true);
|
|
7733
|
+
const [failedOpen, setFailedOpen] = (0, import_react7.useState)(false);
|
|
7459
7734
|
const isConstructionEnforced = Boolean(publicConfig?.construction.enforced);
|
|
7460
|
-
(0,
|
|
7735
|
+
(0, import_react7.useEffect)(() => {
|
|
7461
7736
|
let active = true;
|
|
7462
7737
|
const previewToken = readPreviewToken(config.websiteSlug);
|
|
7463
7738
|
setIsLoading(true);
|
|
@@ -7477,7 +7752,7 @@ function BacanoWebsiteGate({
|
|
|
7477
7752
|
active = false;
|
|
7478
7753
|
};
|
|
7479
7754
|
}, [config.apiUrl, config.origin, config.websiteSlug]);
|
|
7480
|
-
(0,
|
|
7755
|
+
(0, import_react7.useEffect)(() => {
|
|
7481
7756
|
if (typeof document === "undefined" || !isConstructionEnforced) return;
|
|
7482
7757
|
const robots = document.createElement("meta");
|
|
7483
7758
|
robots.name = "robots";
|