@anker-in/shopify-react 1.1.2 → 1.2.0-beta.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.
@@ -1,6 +1,6 @@
1
1
  import { createContext, useMemo, useRef, useState, useEffect, useCallback, useContext } from 'react';
2
2
  import useSWRMutation from 'swr/mutation';
3
- import { getProductsByHandles, createCart, updateCartCodes, addCartLines, getLocalStorage, updateCartLines, removeCartLines, updateCartAttributes, updateBuyerIdentity, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, setLocalStorage } from '@anker-in/shopify-sdk';
3
+ import { getProductsByHandles, createCart, updateCartCodes, addCartLines, removeCartLines, getLocalStorage, updateCartLines, updateCartAttributes, updateBuyerIdentity, getProduct, getAllProducts, getCollection, getAllCollections, getCollections, getBlog, getAllBlogs, getArticle, getArticles, getArticlesInBlog, setLocalStorage } from '@anker-in/shopify-sdk';
4
4
  import Cookies5 from 'js-cookie';
5
5
  import { jsx } from 'react/jsx-runtime';
6
6
  import Decimal2 from 'decimal.js';
@@ -788,15 +788,23 @@ var trackAddToCartGA = ({
788
788
  currency: currencyCode,
789
789
  value: totalPrice,
790
790
  position: gtmParams?.position || "",
791
- items: lineItems.map(({ variant: variant2, quantity }) => ({
792
- item_id: variant2?.sku,
793
- item_name: variant2?.product?.title || variant2?.product?.title,
794
- item_brand: gtmParams?.brand || "",
795
- item_category: variant2?.product?.productType || "",
796
- item_variant: variant2?.title || variant2?.title,
797
- price: variant2?.compareAtPrice?.amount ?? variant2?.price?.amount,
798
- quantity: quantity || 1
799
- })),
791
+ items: lineItems.map((item) => {
792
+ const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
793
+ const itemCategoryId = item.gtmParams?.item_category_id;
794
+ const itemVariantId = item.variant?.id ? atobID(item.variant.id) : void 0;
795
+ return {
796
+ item_id: item.variant?.sku,
797
+ item_name: item.variant?.product?.title || item.variant?.product?.title,
798
+ item_brand: gtmParams?.brand || "",
799
+ item_category: item.variant?.product?.productType || "",
800
+ item_variant: item.variant?.title || item.variant?.title,
801
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
802
+ quantity: item.quantity || 1,
803
+ ...imageUrl && { image_url: imageUrl },
804
+ ...itemCategoryId && { item_category_id: itemCategoryId },
805
+ ...itemVariantId && { item_variant_id: itemVariantId }
806
+ };
807
+ }),
800
808
  ...gtmParams?.ga4Params
801
809
  }
802
810
  });
@@ -824,19 +832,73 @@ var trackBuyNowGA = ({
824
832
  position: gtmParams?.position,
825
833
  currency: currencyCode,
826
834
  value: totalPrice,
827
- items: lineItems.map((item) => ({
828
- item_id: item.variant?.sku,
829
- item_name: item.variant?.product?.title || item.variant?.title,
830
- item_brand: gtmParams?.brand || "",
831
- item_category: item.variant?.product?.productType || "",
832
- item_variant: item.variant?.title,
833
- price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
834
- quantity: item.quantity || 1
835
- })),
835
+ items: lineItems.map((item) => {
836
+ const imageUrl = item.variant?.image?.url || item.variant?.product?.images?.[0]?.url;
837
+ const itemCategoryId = item.gtmParams?.item_category_id;
838
+ const itemVariantId = item.variant?.id ? atobID(item.variant.id) : void 0;
839
+ return {
840
+ item_id: item.variant?.sku,
841
+ item_name: item.variant?.product?.title || item.variant?.title,
842
+ item_brand: gtmParams?.brand || "",
843
+ item_category: item.variant?.product?.productType || "",
844
+ item_variant: item.variant?.title,
845
+ price: item.variant?.compareAtPrice?.amount ?? item.variant?.price?.amount,
846
+ quantity: item.quantity || 1,
847
+ ...imageUrl && { image_url: imageUrl },
848
+ ...itemCategoryId !== void 0 && { item_category_id: itemCategoryId },
849
+ ...itemVariantId && { item_variant_id: itemVariantId }
850
+ };
851
+ }),
836
852
  ...gtmParams?.ga4Params
837
853
  }
838
854
  });
839
855
  };
856
+ function waitForGtagReady(timeout = 1e4) {
857
+ return new Promise((resolve, reject) => {
858
+ const start = Date.now();
859
+ function check() {
860
+ if (typeof window !== "undefined" && typeof window.gtag !== "undefined") {
861
+ resolve();
862
+ } else if (Date.now() - start > timeout) {
863
+ reject(new Error("GA4 gtag not loaded"));
864
+ } else {
865
+ setTimeout(check, 50);
866
+ }
867
+ }
868
+ check();
869
+ });
870
+ }
871
+ var getGA4Data = async (measurementId = "G-R0BRMRK4CY") => {
872
+ try {
873
+ await waitForGtagReady();
874
+ const timeoutPromise = new Promise((resolve) => {
875
+ setTimeout(() => {
876
+ resolve({ clientId: "", sessionId: "" });
877
+ }, 300);
878
+ });
879
+ const dataPromise = new Promise((resolve) => {
880
+ if (!window.gtag) {
881
+ resolve({ clientId: "", sessionId: "" });
882
+ return;
883
+ }
884
+ window.gtag("get", measurementId, "client_id", (clientId) => {
885
+ window.gtag("get", measurementId, "session_id", (sessionId) => {
886
+ resolve({
887
+ clientId: clientId || "",
888
+ sessionId: sessionId || ""
889
+ });
890
+ });
891
+ });
892
+ });
893
+ return Promise.race([dataPromise, timeoutPromise]);
894
+ } catch (error) {
895
+ console.error("Failed to get GA4 data:", error);
896
+ return {
897
+ clientId: "",
898
+ sessionId: ""
899
+ };
900
+ }
901
+ };
840
902
 
841
903
  // src/tracking/fbq.ts
842
904
  var trackAddToCartFBQ = ({ lineItems = [] }) => {
@@ -1019,16 +1081,155 @@ var getLinesWithAttributes = ({
1019
1081
  return functionLine;
1020
1082
  });
1021
1083
  };
1084
+ function useRemoveCartLines(options) {
1085
+ const { client, locale, cartCookieAdapter } = useShopify();
1086
+ const { mutateCart, metafieldIdentifiers } = useCartContext();
1087
+ const removeLines = useCallback(
1088
+ async (_key, { arg }) => {
1089
+ const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1090
+ let updatedCart = await removeCartLines(client, {
1091
+ cartId,
1092
+ lineIds,
1093
+ metafieldIdentifiers,
1094
+ cookieAdapter: cartCookieAdapter
1095
+ });
1096
+ if (updatedCart && autoRemoveInvalidCodes) {
1097
+ const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1098
+ if (unApplicableCodes.length > 0) {
1099
+ if (onCodesRemoved) {
1100
+ const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1101
+ if (handledCart) {
1102
+ updatedCart = handledCart;
1103
+ }
1104
+ } else {
1105
+ updatedCart = await updateCartCodes(client, {
1106
+ cartId: updatedCart.id,
1107
+ discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1108
+ metafieldIdentifiers,
1109
+ cookieAdapter: cartCookieAdapter
1110
+ }) || updatedCart;
1111
+ }
1112
+ }
1113
+ }
1114
+ if (updatedCart) {
1115
+ mutateCart(updatedCart);
1116
+ }
1117
+ return updatedCart;
1118
+ },
1119
+ [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1120
+ );
1121
+ return useSWRMutation("remove-cart-lines", removeLines, options);
1122
+ }
1123
+
1124
+ // src/hooks/cart/feature/use-auto-remove-free-gifts.ts
1125
+ function useAutoRemoveFreeGifts(options = {}) {
1126
+ const {
1127
+ removeFunctionGifts = true,
1128
+ removeScriptGifts = true,
1129
+ isGiftLineItem
1130
+ } = options;
1131
+ const [isRemoving, setIsRemoving] = useState(false);
1132
+ const { cart } = useCartContext();
1133
+ const { trigger: removeCartLines2 } = useRemoveCartLines();
1134
+ const giftsToRemove = useMemo(() => {
1135
+ if (!cart?.lineItems) {
1136
+ return [];
1137
+ }
1138
+ return cart.lineItems.filter((item) => {
1139
+ if (removeFunctionGifts) {
1140
+ const functionAttr = item.customAttributes?.find(
1141
+ (attr) => attr.key === "_discounts_function_env"
1142
+ )?.value;
1143
+ if (functionAttr) {
1144
+ try {
1145
+ const functionAttrObj = JSON.parse(functionAttr);
1146
+ if (functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money) {
1147
+ return true;
1148
+ }
1149
+ } catch (error) {
1150
+ console.error("Failed to parse _discounts_function_env:", error);
1151
+ }
1152
+ }
1153
+ }
1154
+ if (removeScriptGifts) {
1155
+ const scriptGiftAttr = item.customAttributes?.find(
1156
+ (attr) => attr.key === "_giveaway_gradient_gifts"
1157
+ );
1158
+ if (scriptGiftAttr) {
1159
+ return true;
1160
+ }
1161
+ }
1162
+ if (isGiftLineItem && isGiftLineItem(item)) {
1163
+ return true;
1164
+ }
1165
+ return false;
1166
+ });
1167
+ }, [cart, removeFunctionGifts, removeScriptGifts, isGiftLineItem]);
1168
+ useEffect(() => {
1169
+ if (isRemoving || giftsToRemove.length === 0) {
1170
+ return;
1171
+ }
1172
+ const performRemoval = async () => {
1173
+ setIsRemoving(true);
1174
+ try {
1175
+ await removeCartLines2({
1176
+ lineIds: giftsToRemove.map((item) => item.id)
1177
+ });
1178
+ } catch (error) {
1179
+ console.error("Failed to remove free gifts:", error);
1180
+ } finally {
1181
+ setIsRemoving(false);
1182
+ }
1183
+ };
1184
+ performRemoval();
1185
+ }, [
1186
+ isRemoving,
1187
+ giftsToRemove,
1188
+ removeCartLines2
1189
+ ]);
1190
+ return {
1191
+ isRemoving
1192
+ };
1193
+ }
1194
+ function isFunctionGift(line) {
1195
+ const functionAttr = line.customAttributes?.find(
1196
+ (attr) => attr.key === "_discounts_function_env"
1197
+ )?.value;
1198
+ if (!functionAttr) {
1199
+ return false;
1200
+ }
1201
+ try {
1202
+ const functionAttrObj = JSON.parse(functionAttr);
1203
+ return Boolean(
1204
+ functionAttrObj.is_gift && functionAttrObj.rule_id && functionAttrObj.spend_sum_money
1205
+ );
1206
+ } catch {
1207
+ return false;
1208
+ }
1209
+ }
1210
+ function isScriptGift(line) {
1211
+ return line.customAttributes?.some(
1212
+ (attr) => attr.key === "_giveaway_gradient_gifts"
1213
+ ) ?? false;
1214
+ }
1215
+ function isBuyGetGift(line) {
1216
+ return line.customAttributes?.some(
1217
+ (attr) => attr.key === "_freegift_related_handlesku"
1218
+ ) ?? false;
1219
+ }
1220
+ function isAnyGift(line) {
1221
+ return isFunctionGift(line) || isScriptGift(line) || isBuyGetGift(line);
1222
+ }
1022
1223
  function useCalcGiftsFromLines({
1023
1224
  lines,
1024
1225
  customer,
1025
1226
  scriptGiveawayKey = CUSTOMER_SCRIPT_GIFT_KEY
1026
1227
  }) {
1027
1228
  const { locale } = useShopify();
1028
- const { cart, autoFreeGiftConfig, gradientGiftsConfig } = useCartContext();
1029
- const functionGift = useCalcAutoFreeGift(cart, autoFreeGiftConfig || [], customer, lines);
1229
+ const { cart, functionAutoFreeGiftConfig, scriptAutoFreeGiftConfig } = useCartContext();
1230
+ const functionGift = useCalcAutoFreeGift(cart, functionAutoFreeGiftConfig || [], customer, lines);
1030
1231
  const scriptGift = useScriptAutoFreeGift({
1031
- campaign: gradientGiftsConfig || null,
1232
+ campaign: scriptAutoFreeGiftConfig,
1032
1233
  _giveaway: scriptGiveawayKey,
1033
1234
  cart,
1034
1235
  locale,
@@ -1063,7 +1264,9 @@ function useCalcGiftsFromLines({
1063
1264
  const variants = product?.variants;
1064
1265
  const variant = Array.isArray(variants) ? variants.find((v) => v.sku === item.sku) : void 0;
1065
1266
  if (!variant) {
1066
- console.warn(`Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`);
1267
+ console.warn(
1268
+ `Script gift: Variant not found for handle=${item.handle}, sku=${item.sku}`
1269
+ );
1067
1270
  return null;
1068
1271
  }
1069
1272
  return {
@@ -1206,6 +1409,19 @@ var getReferralAttributes = () => {
1206
1409
  }
1207
1410
  return [];
1208
1411
  };
1412
+ var getOperatingSystem = () => {
1413
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
1414
+ return "Unknown";
1415
+ }
1416
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera;
1417
+ if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
1418
+ return "IOS";
1419
+ }
1420
+ if (/android/i.test(userAgent)) {
1421
+ return "Android";
1422
+ }
1423
+ return "Unknown";
1424
+ };
1209
1425
  var getUserType = (customer) => {
1210
1426
  let userInfo = Cookies5.get("userInfo");
1211
1427
  if (userInfo) {
@@ -1227,12 +1443,42 @@ var getUserType = (customer) => {
1227
1443
  }
1228
1444
  return "new_user_login";
1229
1445
  };
1230
- function getCartAttributes({
1446
+ function getGA4Attributes(ga4Data) {
1447
+ if (!ga4Data?.clientId && !ga4Data?.sessionId) {
1448
+ return [];
1449
+ }
1450
+ const attributes = [];
1451
+ if (ga4Data.clientId) {
1452
+ attributes.push({
1453
+ key: "_ga4_client_id",
1454
+ value: ga4Data.clientId
1455
+ });
1456
+ }
1457
+ if (ga4Data.sessionId) {
1458
+ attributes.push({
1459
+ key: "_ga4_session_id",
1460
+ value: ga4Data.sessionId
1461
+ });
1462
+ }
1463
+ return attributes;
1464
+ }
1465
+ async function getGA4AttributesAsync() {
1466
+ try {
1467
+ const ga4Data = await getGA4Data();
1468
+ return getGA4Attributes(ga4Data);
1469
+ } catch (error) {
1470
+ console.error("Failed to get GA4 attributes:", error);
1471
+ return [];
1472
+ }
1473
+ }
1474
+ function getCartBasicAttributes({
1231
1475
  profile,
1232
1476
  customer,
1233
1477
  cart,
1234
1478
  memberType,
1235
- currentUrl = ""
1479
+ currentUrl = "",
1480
+ appContext,
1481
+ buyPath
1236
1482
  }) {
1237
1483
  const userType = getUserType(customer);
1238
1484
  const memberAttributes = [
@@ -1259,12 +1505,10 @@ function getCartAttributes({
1259
1505
  value: "1"
1260
1506
  });
1261
1507
  }
1262
- const discountCodes = cart?.discountCodes.map((item) => item.code).filter((code) => code) || [];
1263
1508
  const functionAttributes = [
1264
1509
  {
1265
1510
  key: CUSTOMER_ATTRIBUTE_KEY,
1266
1511
  value: JSON.stringify({
1267
- discount_code: discountCodes,
1268
1512
  user_tags: customer?.tags || []
1269
1513
  })
1270
1514
  }
@@ -1272,26 +1516,38 @@ function getCartAttributes({
1272
1516
  const presellAttributes = [
1273
1517
  {
1274
1518
  key: "_presale",
1275
- value: cart?.lineItems.some((item) => item?.variant?.metafields?.presell === "presell")
1519
+ value: cart?.lineItems?.some((item) => item?.variant?.metafields?.presell === "presell")
1276
1520
  }
1277
1521
  ];
1278
1522
  const weightAttributes = [
1279
1523
  {
1280
1524
  key: "_weight",
1281
- value: cart?.lineItems.reduce((acc, item) => {
1525
+ value: cart?.lineItems?.reduce((acc, item) => {
1282
1526
  const itemWeight = new Decimal2(item.variant.weight ?? 0).times(item.quantity);
1283
1527
  return new Decimal2(acc).plus(itemWeight).toNumber();
1284
1528
  }, 0).toString()
1285
- },
1286
- {
1287
- key: "_app_source_name",
1288
- value: "dtc"
1289
1529
  }
1290
1530
  ];
1291
1531
  const trackingAttributes = [
1292
1532
  {
1293
1533
  key: "utm_params",
1294
1534
  value: currentUrl
1535
+ },
1536
+ {
1537
+ key: "_app_source_name",
1538
+ value: appContext?.isInApp && appContext?.appName ? appContext.appName : "dtc"
1539
+ },
1540
+ {
1541
+ key: "_operating_system",
1542
+ value: getOperatingSystem()
1543
+ },
1544
+ {
1545
+ key: "_cart_id",
1546
+ value: cart?.id
1547
+ },
1548
+ {
1549
+ key: "_buy_path",
1550
+ value: buyPath
1295
1551
  }
1296
1552
  ];
1297
1553
  const commonAttributes = [
@@ -1311,21 +1567,41 @@ var useCartAttributes = ({
1311
1567
  profile,
1312
1568
  customer,
1313
1569
  cart,
1314
- memberType
1570
+ memberType,
1571
+ appContext,
1572
+ buyPath
1315
1573
  }) => {
1316
1574
  const [currentUrl, setCurrentUrl] = useState("");
1575
+ const [ga4Data, setGa4Data] = useState(null);
1317
1576
  useEffect(() => {
1318
1577
  setCurrentUrl(window.location.href);
1319
1578
  }, []);
1579
+ useEffect(() => {
1580
+ let isMounted = true;
1581
+ getGA4Data().then((data) => {
1582
+ if (isMounted) {
1583
+ setGa4Data(data);
1584
+ }
1585
+ }).catch((error) => {
1586
+ console.error("Failed to get GA4 data in useCartAttributes:", error);
1587
+ });
1588
+ return () => {
1589
+ isMounted = false;
1590
+ };
1591
+ }, []);
1320
1592
  const attributes = useMemo(() => {
1321
- return getCartAttributes({
1593
+ const basicAttributes = getCartBasicAttributes({
1322
1594
  profile,
1323
1595
  customer,
1324
1596
  cart,
1325
1597
  memberType,
1326
- currentUrl
1598
+ currentUrl,
1599
+ appContext,
1600
+ buyPath
1327
1601
  });
1328
- }, [profile, customer, cart, memberType, currentUrl]);
1602
+ const ga4Attributes = getGA4Attributes(ga4Data);
1603
+ return [...basicAttributes, ...ga4Attributes];
1604
+ }, [profile, customer, cart, memberType, currentUrl, appContext, buyPath, ga4Data]);
1329
1605
  return useMemo(
1330
1606
  () => ({
1331
1607
  attributes
@@ -1388,12 +1664,9 @@ var useUpdateLineCodeAmountAttributes = ({
1388
1664
  const codeDiscount = line.discountAllocations?.find(
1389
1665
  (allocation) => mainProductDiscountCodes?.includes(allocation.code)
1390
1666
  );
1391
- const hasFunctionEnvAttribute = line.customAttributes?.find(
1392
- (attr) => attr.key === CUSTOMER_ATTRIBUTE_KEY
1393
- );
1394
1667
  const functionEnvValue = getDiscountEnvAttributeValue(line.customAttributes);
1395
1668
  const hasSameFunctionEnvAttribute = Number(functionEnvValue.discounted_amount) === Number(line.totalAmount);
1396
- if (!hasSameFunctionEnvAttribute && hasFunctionEnvAttribute && !functionEnvValue.is_gift) {
1669
+ if (!hasSameFunctionEnvAttribute && !functionEnvValue.is_gift) {
1397
1670
  attrNeedUpdate.push({
1398
1671
  key: CUSTOMER_ATTRIBUTE_KEY,
1399
1672
  value: JSON.stringify({
@@ -1814,47 +2087,6 @@ var usePlusMemberCheckoutCustomAttributes = ({
1814
2087
  return checkoutCustomAttributes;
1815
2088
  }, [profile, selectedShippingMethod, selectedPlusMemberMode, isPresaleContains]);
1816
2089
  };
1817
- function useRemoveCartLines(options) {
1818
- const { client, locale, cartCookieAdapter } = useShopify();
1819
- const { mutateCart, metafieldIdentifiers } = useCartContext();
1820
- const removeLines = useCallback(
1821
- async (_key, { arg }) => {
1822
- const { autoRemoveInvalidCodes = true, onCodesRemoved, cartId, lineIds } = arg;
1823
- let updatedCart = await removeCartLines(client, {
1824
- cartId,
1825
- lineIds,
1826
- metafieldIdentifiers,
1827
- cookieAdapter: cartCookieAdapter
1828
- });
1829
- if (updatedCart && autoRemoveInvalidCodes) {
1830
- const unApplicableCodes = updatedCart.discountCodes.filter((item) => !item.applicable).map((item) => item.code);
1831
- if (unApplicableCodes.length > 0) {
1832
- if (onCodesRemoved) {
1833
- const handledCart = await onCodesRemoved(updatedCart, unApplicableCodes);
1834
- if (handledCart) {
1835
- updatedCart = handledCart;
1836
- }
1837
- } else {
1838
- updatedCart = await updateCartCodes(client, {
1839
- cartId: updatedCart.id,
1840
- discountCodes: updatedCart.discountCodes.filter((item) => item.applicable).map((item) => item.code),
1841
- metafieldIdentifiers,
1842
- cookieAdapter: cartCookieAdapter
1843
- }) || updatedCart;
1844
- }
1845
- }
1846
- }
1847
- if (updatedCart) {
1848
- mutateCart(updatedCart);
1849
- }
1850
- return updatedCart;
1851
- },
1852
- [client, locale, cartCookieAdapter, mutateCart, metafieldIdentifiers]
1853
- );
1854
- return useSWRMutation("remove-cart-lines", removeLines, options);
1855
- }
1856
-
1857
- // src/hooks/member/plus/use-auto-remove-plus-member-in-cart.ts
1858
2090
  function useAutoRemovePlusMemberInCart({
1859
2091
  cart,
1860
2092
  profile,
@@ -2069,7 +2301,8 @@ function useAddToCart({ withTrack = true } = {}, swrOptions) {
2069
2301
  profile,
2070
2302
  customer,
2071
2303
  cart,
2072
- memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0)
2304
+ memberType: hasPlusMember ? "2" : String(profile?.memberType ?? 0),
2305
+ buyPath: "hasCart"
2073
2306
  });
2074
2307
  const addToCart = useCallback(
2075
2308
  async (_key, { arg }) => {
@@ -2242,7 +2475,7 @@ function useUpdateBuyerIdentity({
2242
2475
  }
2243
2476
  function useBuyNow({ withTrack = true } = {}, swrOptions) {
2244
2477
  const { client, config, locale, cartCookieAdapter, userAdapter } = useShopify();
2245
- const { profile, customer, memberSetting } = useCartContext();
2478
+ const { profile, customer, memberSetting, appContext } = useCartContext();
2246
2479
  const isLoggedIn = userAdapter?.isLoggedIn || false;
2247
2480
  const buyNow = useCallback(
2248
2481
  async (_key, { arg }) => {
@@ -2264,12 +2497,6 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2264
2497
  lines: lineItems
2265
2498
  });
2266
2499
  const memberType = hasPlusMember ? "2" : String(profile?.memberType ?? 0);
2267
- const cartAttributes = getCartAttributes({
2268
- profile,
2269
- customer,
2270
- memberType,
2271
- currentUrl: window.location.href
2272
- });
2273
2500
  const linesWithFunctionAttributes = getLinesWithAttributes({
2274
2501
  lineItems
2275
2502
  });
@@ -2282,13 +2509,23 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2282
2509
  if (lines.length === 0) {
2283
2510
  return;
2284
2511
  }
2512
+ const basicCartAttributes = getCartBasicAttributes({
2513
+ profile,
2514
+ customer,
2515
+ memberType,
2516
+ cart: { lineItems },
2517
+ currentUrl: window.location.href,
2518
+ appContext,
2519
+ buyPath: "buyNow"
2520
+ });
2521
+ const ga4Attributes = await getGA4AttributesAsync();
2285
2522
  const resultCart = await createCart(client, {
2286
2523
  lines,
2287
2524
  metafieldIdentifiers,
2288
2525
  cookieAdapter: cartCookieAdapter,
2289
2526
  buyerIdentity,
2290
2527
  discountCodes,
2291
- customAttributes: [...cartAttributes, ...customAttributes || []]
2528
+ customAttributes: [...basicCartAttributes, ...ga4Attributes, ...customAttributes || []]
2292
2529
  });
2293
2530
  if (!resultCart) {
2294
2531
  throw new Error("Failed to create cart for buy now");
@@ -2313,7 +2550,17 @@ function useBuyNow({ withTrack = true } = {}, swrOptions) {
2313
2550
  }
2314
2551
  return resultCart;
2315
2552
  },
2316
- [client, locale, isLoggedIn, cartCookieAdapter, withTrack, customer, profile, memberSetting]
2553
+ [
2554
+ client,
2555
+ locale,
2556
+ isLoggedIn,
2557
+ cartCookieAdapter,
2558
+ withTrack,
2559
+ customer,
2560
+ profile,
2561
+ memberSetting,
2562
+ appContext
2563
+ ]
2317
2564
  );
2318
2565
  return useSWRMutation("buy-now", buyNow, swrOptions);
2319
2566
  }
@@ -3106,6 +3353,6 @@ function clearGeoLocationCache(cacheKey = "geoLocation") {
3106
3353
  }
3107
3354
  }
3108
3355
 
3109
- export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getCartAttributes, getDiscountEnvAttributeValue, getMatchedMainProductSubTotal, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useSite, useUpdateBuyerIdentity, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3356
+ export { BuyRuleType, CODE_AMOUNT_KEY, CUSTOMER_ATTRIBUTE_KEY, CUSTOMER_SCRIPT_GIFT_KEY, DeliveryPlusType, MAIN_PRODUCT_CODE, MEMBER_PRICE_ATTRIBUTE_KEY, OrderBasePriceType, OrderDiscountType, PLUS_MEMBER_TYPE, PlusMemberContext, PlusMemberMode, PlusMemberProvider, PriceBasePriceType, PriceDiscountType, RuleType, SCRIPT_CODE_AMOUNT_KEY, ShippingMethodMode, SpendMoneyType, clearGeoLocationCache, createMockCartFromLines, currencyCodeMapping, defaultSWRMutationConfiguration, formatFunctionAutoFreeGift, formatScriptAutoFreeGift, getCachedGeoLocation, getCartBasicAttributes, getDiscountEnvAttributeValue, getGA4Attributes, getGA4AttributesAsync, getMatchedMainProductSubTotal, getOperatingSystem, getQuery, getReferralAttributes, getUserType, hasPlusMemberInCart, hasPlusMemberInLines, isAnyGift, isBuyGetGift, isFunctionGift, isScriptGift, normalizeAddToCartLines, preCheck, safeParse, useAddCartLines, useAddToCart, useAllBlogs, useAllCollections, useAllProducts, useApplyCartCodes, useArticle, useArticles, useArticlesInBlog, useAutoRemoveFreeGifts, useAutoRemovePlusMemberInCart, useAvailableDeliveryCoupon, useBlog, useBuyNow, useCalcAutoFreeGift, useCalcGiftsFromLines, useCalcOrderDiscount, useCartAttributes, useCartItemQuantityLimit, useCollection, useCollections, useCreateCart, useExposure, useGeoLocation, useHasPlusMemberInCart, useHasPlusMemberInLines, useIntersection, usePlusMemberCheckoutCustomAttributes, usePlusMemberContext, usePlusMemberNeedAddToCart, usePlusMemberVariants, usePrice, useProduct, useProductUrl, useProductsByHandles, useRemoveCartCodes, useRemoveCartLines, useReplaceCartPlusMember, useScriptAutoFreeGift, useSearch, useSelectedOptions, useShippingMethods, useSite, useUpdateBuyerIdentity, useUpdateCartAttributes, useUpdateCartLines, useUpdateLineCodeAmountAttributes, useUpdateVariantQuery, useVariant, useVariantMedia };
3110
3357
  //# sourceMappingURL=index.mjs.map
3111
3358
  //# sourceMappingURL=index.mjs.map