@rebuy/rebuy-hydrogen 3.0.0-beta.13 → 3.0.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +669 -111
  2. package/dist/components/AddToCartBtn/AddToCartBtn.d.ts +1 -1
  3. package/dist/components/AddToCartBtn/AddToCartBtn.d.ts.map +1 -1
  4. package/dist/components/AddToCartBtn/HydrogenAddToCartBtn.d.ts +1 -1
  5. package/dist/components/AddToCartBtn/HydrogenAddToCartBtn.d.ts.map +1 -1
  6. package/dist/components/AddToCartBtn/HydrogenReactAddToCartBtn.d.ts +1 -1
  7. package/dist/components/AddToCartBtn/HydrogenReactAddToCartBtn.d.ts.map +1 -1
  8. package/dist/components/AddToCartBtn/types.d.ts +4 -0
  9. package/dist/components/AddToCartBtn/types.d.ts.map +1 -1
  10. package/dist/components/ProductCard/ProductCard.d.ts +1 -1
  11. package/dist/components/ProductCard/ProductCard.d.ts.map +1 -1
  12. package/dist/components/ProductCard/types.d.ts +3 -0
  13. package/dist/components/ProductCard/types.d.ts.map +1 -1
  14. package/dist/components/ProductCarousel/ProductCarousel.d.ts +2 -1
  15. package/dist/components/ProductCarousel/ProductCarousel.d.ts.map +1 -1
  16. package/dist/components/ProductPrice/ProductPrice.d.ts.map +1 -1
  17. package/dist/components/QuantityInput/QuantityInput.d.ts +1 -1
  18. package/dist/components/QuantityInput/QuantityInput.d.ts.map +1 -1
  19. package/dist/components/Timer/Timer.d.ts.map +1 -1
  20. package/dist/components/Timer/types.d.ts +2 -2
  21. package/dist/components/Timer/types.d.ts.map +1 -1
  22. package/dist/components/VariantSelect/VariantSelect.d.ts.map +1 -1
  23. package/dist/constants/debug.d.ts +27 -0
  24. package/dist/constants/debug.d.ts.map +1 -0
  25. package/dist/context/RebuyConfigContext.d.ts +2 -0
  26. package/dist/context/RebuyConfigContext.d.ts.map +1 -1
  27. package/dist/hooks/useBreakpoint.d.ts +1 -1
  28. package/dist/hooks/useBreakpoint.d.ts.map +1 -1
  29. package/dist/hooks/usePopupTrigger.d.ts +1 -1
  30. package/dist/hooks/usePopupTrigger.d.ts.map +1 -1
  31. package/dist/index.css +2513 -518
  32. package/dist/index.css.map +4 -4
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +8948 -2513
  36. package/dist/index.js.map +4 -4
  37. package/dist/index.mjs +8963 -2528
  38. package/dist/index.mjs.map +4 -4
  39. package/dist/providers/RebuyHydrogenContextProvider.d.ts +1 -1
  40. package/dist/providers/RebuyHydrogenContextProvider.d.ts.map +1 -1
  41. package/dist/providers/RebuyHydrogenReactContextProvider.d.ts +1 -1
  42. package/dist/providers/RebuyHydrogenReactContextProvider.d.ts.map +1 -1
  43. package/dist/providers/types.d.ts +14 -22
  44. package/dist/providers/types.d.ts.map +1 -1
  45. package/dist/queries/cart.queries.d.ts +4 -4
  46. package/dist/queries/cart.queries.d.ts.map +1 -1
  47. package/dist/smart-cart/RebuySmartCart.d.ts +10 -0
  48. package/dist/smart-cart/RebuySmartCart.d.ts.map +1 -0
  49. package/dist/smart-cart/components/AnnouncementBar/AnnouncementBar.d.ts +10 -0
  50. package/dist/smart-cart/components/AnnouncementBar/AnnouncementBar.d.ts.map +1 -0
  51. package/dist/smart-cart/components/CartItem/CartItem.d.ts +7 -0
  52. package/dist/smart-cart/components/CartItem/CartItem.d.ts.map +1 -0
  53. package/dist/smart-cart/components/CartItemList/CartItemList.d.ts +10 -0
  54. package/dist/smart-cart/components/CartItemList/CartItemList.d.ts.map +1 -0
  55. package/dist/smart-cart/components/CartNoteInput/CartNoteInput.d.ts +10 -0
  56. package/dist/smart-cart/components/CartNoteInput/CartNoteInput.d.ts.map +1 -0
  57. package/dist/smart-cart/components/CartSubtotal/CartSubtotal.d.ts +11 -0
  58. package/dist/smart-cart/components/CartSubtotal/CartSubtotal.d.ts.map +1 -0
  59. package/dist/smart-cart/components/CartTitleBar/CartTitleBar.d.ts +7 -0
  60. package/dist/smart-cart/components/CartTitleBar/CartTitleBar.d.ts.map +1 -0
  61. package/dist/smart-cart/components/CheckoutArea/CheckoutArea.d.ts +10 -0
  62. package/dist/smart-cart/components/CheckoutArea/CheckoutArea.d.ts.map +1 -0
  63. package/dist/smart-cart/components/CrossSell/CrossSell.d.ts +10 -0
  64. package/dist/smart-cart/components/CrossSell/CrossSell.d.ts.map +1 -0
  65. package/dist/smart-cart/components/CustomCode/CustomCodeBlock.d.ts +21 -0
  66. package/dist/smart-cart/components/CustomCode/CustomCodeBlock.d.ts.map +1 -0
  67. package/dist/smart-cart/components/DebugPanel/DebugPanel.d.ts +13 -0
  68. package/dist/smart-cart/components/DebugPanel/DebugPanel.d.ts.map +1 -0
  69. package/dist/smart-cart/components/DebugPanel/index.d.ts +11 -0
  70. package/dist/smart-cart/components/DebugPanel/index.d.ts.map +1 -0
  71. package/dist/smart-cart/components/DiscountCodeInput/DiscountCodeInput.d.ts +10 -0
  72. package/dist/smart-cart/components/DiscountCodeInput/DiscountCodeInput.d.ts.map +1 -0
  73. package/dist/smart-cart/components/EmptyCart/EmptyCart.d.ts +3 -0
  74. package/dist/smart-cart/components/EmptyCart/EmptyCart.d.ts.map +1 -0
  75. package/dist/smart-cart/components/LoginButton/LoginButton.d.ts +3 -0
  76. package/dist/smart-cart/components/LoginButton/LoginButton.d.ts.map +1 -0
  77. package/dist/smart-cart/components/ScreenReaderText/ScreenReaderText.d.ts +8 -0
  78. package/dist/smart-cart/components/ScreenReaderText/ScreenReaderText.d.ts.map +1 -0
  79. package/dist/smart-cart/components/SmartCartApp/SmartCartApp.d.ts +20 -0
  80. package/dist/smart-cart/components/SmartCartApp/SmartCartApp.d.ts.map +1 -0
  81. package/dist/smart-cart/components/SmartCartContainer/SmartCartContainer.d.ts +8 -0
  82. package/dist/smart-cart/components/SmartCartContainer/SmartCartContainer.d.ts.map +1 -0
  83. package/dist/smart-cart/components/TieredProgressBar/Icons.d.ts +5 -0
  84. package/dist/smart-cart/components/TieredProgressBar/Icons.d.ts.map +1 -0
  85. package/dist/smart-cart/components/TieredProgressBar/TPBGiftItem.d.ts +21 -0
  86. package/dist/smart-cart/components/TieredProgressBar/TPBGiftItem.d.ts.map +1 -0
  87. package/dist/smart-cart/components/TieredProgressBar/TieredProgressBar.d.ts +11 -0
  88. package/dist/smart-cart/components/TieredProgressBar/TieredProgressBar.d.ts.map +1 -0
  89. package/dist/smart-cart/components/TieredProgressBar/progressBarUtils.d.ts +173 -0
  90. package/dist/smart-cart/components/TieredProgressBar/progressBarUtils.d.ts.map +1 -0
  91. package/dist/smart-cart/components/TieredProgressBar/types.d.ts +261 -0
  92. package/dist/smart-cart/components/TieredProgressBar/types.d.ts.map +1 -0
  93. package/dist/smart-cart/components/_Layouts/AnchorSlot.d.ts +13 -0
  94. package/dist/smart-cart/components/_Layouts/AnchorSlot.d.ts.map +1 -0
  95. package/dist/smart-cart/components/_Layouts/DoubleColumnLayout.d.ts +9 -0
  96. package/dist/smart-cart/components/_Layouts/DoubleColumnLayout.d.ts.map +1 -0
  97. package/dist/smart-cart/components/_Layouts/SingleColumnLayout.d.ts +8 -0
  98. package/dist/smart-cart/components/_Layouts/SingleColumnLayout.d.ts.map +1 -0
  99. package/dist/smart-cart/components/componentRegistry.d.ts +3 -0
  100. package/dist/smart-cart/components/componentRegistry.d.ts.map +1 -0
  101. package/dist/smart-cart/constants.d.ts +57 -0
  102. package/dist/smart-cart/constants.d.ts.map +1 -0
  103. package/dist/smart-cart/context/SmartCartContext.d.ts +62 -0
  104. package/dist/smart-cart/context/SmartCartContext.d.ts.map +1 -0
  105. package/dist/smart-cart/context/StorefrontCartContext.d.ts +32 -0
  106. package/dist/smart-cart/context/StorefrontCartContext.d.ts.map +1 -0
  107. package/dist/smart-cart/hooks/useCartItemFeatures.d.ts +84 -0
  108. package/dist/smart-cart/hooks/useCartItemFeatures.d.ts.map +1 -0
  109. package/dist/smart-cart/hooks/useDiscountManager.d.ts +28 -0
  110. package/dist/smart-cart/hooks/useDiscountManager.d.ts.map +1 -0
  111. package/dist/smart-cart/hooks/useGeolocation.d.ts +12 -0
  112. package/dist/smart-cart/hooks/useGeolocation.d.ts.map +1 -0
  113. package/dist/smart-cart/hooks/useIsScrolled.d.ts +14 -0
  114. package/dist/smart-cart/hooks/useIsScrolled.d.ts.map +1 -0
  115. package/dist/smart-cart/hooks/useSmartCartApps.d.ts +17 -0
  116. package/dist/smart-cart/hooks/useSmartCartApps.d.ts.map +1 -0
  117. package/dist/smart-cart/store/tieredProgressBarStore.d.ts +76 -0
  118. package/dist/smart-cart/store/tieredProgressBarStore.d.ts.map +1 -0
  119. package/dist/smart-cart/types/rebuy-storefront-cart.d.ts +142 -0
  120. package/dist/smart-cart/types/rebuy-storefront-cart.d.ts.map +1 -0
  121. package/dist/smart-cart/types/rebuy.d.ts +15 -0
  122. package/dist/smart-cart/types/rebuy.d.ts.map +1 -0
  123. package/dist/smart-cart/types/shop.d.ts +26 -0
  124. package/dist/smart-cart/types/shop.d.ts.map +1 -0
  125. package/dist/smart-cart/types/smart-cart-app.d.ts +103 -0
  126. package/dist/smart-cart/types/smart-cart-app.d.ts.map +1 -0
  127. package/dist/smart-cart/types/smart-cart-component.d.ts +1350 -0
  128. package/dist/smart-cart/types/smart-cart-component.d.ts.map +1 -0
  129. package/dist/smart-cart/types/smart-cart.d.ts +82 -0
  130. package/dist/smart-cart/types/smart-cart.d.ts.map +1 -0
  131. package/dist/smart-cart/utils/cartItemUtils.d.ts +292 -0
  132. package/dist/smart-cart/utils/cartItemUtils.d.ts.map +1 -0
  133. package/dist/smart-cart/utils/debugLog.d.ts +77 -0
  134. package/dist/smart-cart/utils/debugLog.d.ts.map +1 -0
  135. package/dist/smart-cart/utils/debugStyles.d.ts +3342 -0
  136. package/dist/smart-cart/utils/debugStyles.d.ts.map +1 -0
  137. package/dist/smart-cart/utils/executeScriptsInContainer.d.ts +14 -0
  138. package/dist/smart-cart/utils/executeScriptsInContainer.d.ts.map +1 -0
  139. package/dist/smart-cart/utils/imageUtils.d.ts +2 -0
  140. package/dist/smart-cart/utils/imageUtils.d.ts.map +1 -0
  141. package/dist/smart-cart/utils/mapHydrogenCartToStorefrontCartData.d.ts +14 -0
  142. package/dist/smart-cart/utils/mapHydrogenCartToStorefrontCartData.d.ts.map +1 -0
  143. package/dist/smart-cart/utils/moneyUtils.d.ts +24 -0
  144. package/dist/smart-cart/utils/moneyUtils.d.ts.map +1 -0
  145. package/dist/smart-cart/utils/safeJsonParse.d.ts +2 -0
  146. package/dist/smart-cart/utils/safeJsonParse.d.ts.map +1 -0
  147. package/dist/types/common.d.ts +9 -0
  148. package/dist/types/common.d.ts.map +1 -1
  149. package/dist/types/rebuyCustom.d.ts +86 -6
  150. package/dist/types/rebuyCustom.d.ts.map +1 -1
  151. package/dist/types/widgets.d.ts +20068 -0
  152. package/dist/types/widgets.d.ts.map +1 -1
  153. package/dist/utils/createContextParameters.d.ts.map +1 -1
  154. package/dist/utils/filterContextUtils.d.ts +3 -0
  155. package/dist/utils/filterContextUtils.d.ts.map +1 -0
  156. package/dist/utils/nonceManager.d.ts +10 -0
  157. package/dist/utils/nonceManager.d.ts.map +1 -0
  158. package/dist/widgetContainer/RebuyWidgetContainer.d.ts.map +1 -1
  159. package/dist/widgets/RebuyCompleteTheLook/RebuyCompleteTheLook.d.ts.map +1 -1
  160. package/dist/widgets/RebuyDynamicBundleProducts/BundleSelection.d.ts.map +1 -1
  161. package/dist/widgets/RebuyDynamicBundleProducts/RebuyDynamicBundleProducts.d.ts.map +1 -1
  162. package/dist/widgets/RebuyProductAddOns/RebuyProductAddOns.d.ts.map +1 -1
  163. package/dist/widgets/RebuyProductRecommendations/RebuyProductRecommendations.d.ts.map +1 -1
  164. package/dist/widgets/RebuyWidget/RebuyWidget.d.ts.map +1 -1
  165. package/dist/widgets/RebuyWidget/WidgetContent.d.ts +1 -1
  166. package/dist/widgets/RebuyWidget/WidgetContent.d.ts.map +1 -1
  167. package/dist/widgets/RebuyWidget/types.d.ts +3 -314
  168. package/dist/widgets/RebuyWidget/types.d.ts.map +1 -1
  169. package/package.json +14 -8
  170. package/dist/hooks/useRebuyTheme.d.ts +0 -21
  171. package/dist/hooks/useRebuyTheme.d.ts.map +0 -1
  172. package/dist/types/rebuySmartCart.d.ts +0 -184
  173. package/dist/types/rebuySmartCart.d.ts.map +0 -1
  174. package/dist/utils/csp.d.ts +0 -16
  175. package/dist/utils/csp.d.ts.map +0 -1
package/README.md CHANGED
@@ -2,9 +2,20 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- The new beta version of our Rebuy Hydrogen package is designed to work with both Hydrogen and Hydrogen React versions 2.0. We've streamlined this package to be as plug-and-play as possible, with the package handling most of the work. Below you'll find descriptions of each component and implementation instructions for your application.
5
+ The new beta version of our Rebuy Hydrogen package is designed to work with both Hydrogen and Hydrogen React versions 2.0. We've streamlined this package to be as plug-and-play as possible, with the package handling most of the work.
6
6
 
7
- ## Initial Setup
7
+ ## Quick Reference
8
+
9
+ This documentation covers:
10
+
11
+ - **Installation** - Setup for Hydrogen and Hydrogen React applications
12
+ - **Themed Styles** - Automatic styling integration with your Rebuy admin settings
13
+ - **Components** - WidgetContainer, product recommendations, bundles, and more
14
+ - **Smart Cart** - Advanced cart features including discount codes and subscriptions
15
+
16
+ ---
17
+
18
+ # 📦 Installation Guide
8
19
 
9
20
  ### Prerequisites
10
21
 
@@ -19,38 +30,36 @@ This distinction is important as different hooks/functions are used in each case
19
30
 
20
31
  1. Install the beta version of our package from npm:
21
32
 
33
+ ```bash
34
+ npm i @rebuy/rebuy-hydrogen@3.0.0-beta.15
22
35
  ```
23
- npm i @rebuy/rebuy-hydrogen@3.0.0-beta.13
24
- ```
25
-
26
- Package URL: [https://www.npmjs.com/package/@rebuy/rebuy-hydrogen](https://www.npmjs.com/package/@rebuy/rebuy-hydrogen)
27
-
28
36
 
37
+ Package URL: [https://www.npmjs.com/package/@rebuy/rebuy-hydrogen](https://www.npmjs.com/package/@rebuy/rebuy-hydrogen)
29
38
 
30
- 2\. In your entry.server.tsx add update the creatContentSecurityPolicy to have the [rebuyengine.com](http://rebuyengine.com) in the connectSrc
39
+ 2. In your server entry file (typically `app/entry.server.tsx`), update the `createContentSecurityPolicy` to have `rebuyengine.com` in the `connectSrc`.
31
40
 
32
- ```
33
- const {nonce, header, NonceProvider} = createContentSecurityPolicy({
41
+ ```typescript
42
+ const { nonce, header, NonceProvider } = createContentSecurityPolicy({
34
43
  shop: {
35
- checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
36
- storeDomain: context.env.PUBLIC_STORE_DOMAIN,
44
+ checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
45
+ storeDomain: context.env.PUBLIC_STORE_DOMAIN,
37
46
  },
38
- connectSrc: ['*.rebuyengine.com', 'rebuyengine.com']
39
- });
47
+ connectSrc: ['*.rebuyengine.com', 'rebuyengine.com'],
48
+ });
40
49
  ```
41
50
 
42
- ### For Hydrogen-only Applications:
51
+ ### For Hydrogen-only Applications
43
52
 
44
- 1. Navigate to your `app/root.tsx` file and add the following imports:
53
+ 1. Navigate to your root layout file (typically `app/root.tsx`) and add the following imports:
45
54
 
46
- ```
55
+ ```typescript
47
56
  import { RebuyHydrogenContextProvider } from '@rebuy/rebuy-hydrogen';
48
57
  import '@rebuy/rebuy-hydrogen/dist/index.css';
49
58
  ```
50
59
 
51
- 2. Place the `<RebuyHydrogenContextProvider>` component as the parent component after the body. Required props: `cart.data` and `shop(domain) and publicStoreDomain (domain.myshopify.com)`.
60
+ 2. Place the `<RebuyHydrogenContextProvider>` component as the parent component after the body. Required props: `cart.data`, `shop` (your store's domain), and `publicStoreDomain` (e.g., "example.myshopify.com").
52
61
 
53
- ```
62
+ ```typescript
54
63
  {data ? (
55
64
  <RebuyHydrogenContextProvider cart={data.cart} shop="example.com" publicStoreDomain="example.myshopify.com"
56
65
  >
@@ -69,57 +78,109 @@ import '@rebuy/rebuy-hydrogen/dist/index.css';
69
78
  )}
70
79
  ```
71
80
 
72
- ### For Hydrogen React Applications:
81
+ ### For Hydrogen React Applications
73
82
 
74
- 1. Navigate to your `app/root.tsx` file and add the import for the CSS:
83
+ 1. Navigate to your root layout file (typically `app/root.tsx`) and add the import for the CSS:
75
84
 
76
- ```
85
+ ```typescript
77
86
  import '@rebuy/rebuy-hydrogen/dist/index.css';
78
87
  ```
79
88
 
80
- 2. Navigate to where your context providers are located and wrap the `RebuyHydrogenReactContextProvider` around the children. Required Props: `shop(domain) and publicStoreDomain (domain.myshopify.com)` For Pack Digital users, this would be in `app/context/ContextProvider.tsx`:
89
+ 2. Navigate to where your context providers are located and wrap the `RebuyHydrogenReactContextProvider` around the children. Required Props: `publicPrimaryDomain` (your shop's main domain, e.g., "example.com"), `publicStoreDomain` (your Shopify domain, e.g., "example.myshopify.com"), `publicStorefrontToken` (your public storefront API token), and `publicStorefrontId` (your storefront ID). For Pack Digital users, this would typically be in `app/context/ContextProvider.tsx`:
81
90
 
82
- ```
83
- <RebuyHydrogenReactContextProvider publicPrimaryDomian="example.com" publicStoreDomain="example.myshopify.com" publicStorefrontApiToken="1233456" publicStorefrontId="12345678" >
91
+ ```typescript
92
+ <RebuyHydrogenReactContextProvider publicPrimaryDomain="example.com" publicStoreDomain="example.myshopify.com" publicStorefrontToken="1233456" publicStorefrontId="12345678" >
84
93
  {children}
85
94
  </RebuyHydrogenReactContextProvider>
86
95
  ```
87
96
 
88
- 3. With this you can also pass in any CartProvider props that you need to pass in.
89
-
90
- - # Cart Provider Properties
91
-
92
- | Property | Type | Required | Description |
93
- | :---- | :---- | :---- | :---- |
94
- | `children` | `React.ReactNode` | Yes | Any `ReactNode` elements. |
95
- | `numCartLines` | `number` | No | Maximum number of cart lines to fetch. Defaults to 250 cart lines. |
96
- | `onCreate` | `() => void` | No | A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. |
97
- | `onLineAdd` | `() => void` | No | A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. |
98
- | `onLineRemove` | `() => void` | No | A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. |
99
- | `onLineUpdate` | `() => void` | No | A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. |
100
- | `onNoteUpdate` | `() => void` | No | A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. |
101
- | `onBuyerIdentityUpdate` | `() => void` | No | A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. |
102
- | `onAttributesUpdate` | `() => void` | No | A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. |
103
- | `onDiscountCodesUpdate` | `() => void` | No | A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. |
104
- | `onCreateComplete` | `() => void` | No | A callback that is invoked when the process to create a cart completes. |
105
- | `onLineAddComplete` | `() => void` | No | A callback that is invoked when the process to add a line item to the cart completes. |
106
- | `onLineRemoveComplete` | `() => void` | No | A callback that is invoked when the process to remove a line item to the cart completes. |
107
- | `onLineUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update a line item in the cart completes. |
108
- | `onNoteUpdateComplete` | `() => void` | No | A callback that is invoked when the process to add or update a note in the cart completes. |
109
- | `onBuyerIdentityUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the buyer identity completes. |
110
- | `onAttributesUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the cart attributes completes. |
111
- | `onDiscountCodesUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the cart discount codes completes. |
112
- | `data` | `PartialDeep<CartType, {recurseIntoArrays: true}>` | No | An object with fields that correspond to the Storefront API's Cart object. |
113
- | `cartFragment` | `string` | No | A fragment used to query the Storefront API's Cart object for all queries and mutations. A default value is used if no argument is provided. |
114
- | `customerAccessToken` | `string` | No | A customer access token that's accessible on the server if there's a customer login. |
115
- | `countryCode` | `CountryCode` | No | The ISO country code for i18n. |
116
-
117
- -
118
-
119
- ## Override key
120
- If you need to pass in a different Rebuy Api key from the one that we dynamically use for your store, you can pass it in as a prop on either of the provider components. ie `overrideApiKey="123456"`
121
-
122
- ## Components
97
+ 3. With this, you can also pass in any CartProvider props that you need.
98
+
99
+ ### Cart Provider Properties
100
+
101
+ | Property | Type | Required | Description |
102
+ | :------------------------------ | :------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
103
+ | `children` | `React.ReactNode` | Yes | Any `ReactNode` elements. |
104
+ | `numCartLines` | `number` | No | Maximum number of cart lines to fetch. Defaults to 250 cart lines. |
105
+ | `onCreate` | `() => void` | No | A callback that is invoked when the process to create a cart begins, but before the cart is created in the Storefront API. |
106
+ | `onLineAdd` | `() => void` | No | A callback that is invoked when the process to add a line item to the cart begins, but before the line item is added to the Storefront API. |
107
+ | `onLineRemove` | `() => void` | No | A callback that is invoked when the process to remove a line item to the cart begins, but before the line item is removed from the Storefront API. |
108
+ | `onLineUpdate` | `() => void` | No | A callback that is invoked when the process to update a line item in the cart begins, but before the line item is updated in the Storefront API. |
109
+ | `onNoteUpdate` | `() => void` | No | A callback that is invoked when the process to add or update a note in the cart begins, but before the note is added or updated in the Storefront API. |
110
+ | `onBuyerIdentityUpdate` | `() => void` | No | A callback that is invoked when the process to update the buyer identity begins, but before the buyer identity is updated in the Storefront API. |
111
+ | `onAttributesUpdate` | `() => void` | No | A callback that is invoked when the process to update the cart attributes begins, but before the attributes are updated in the Storefront API. |
112
+ | `onDiscountCodesUpdate` | `() => void` | No | A callback that is invoked when the process to update the cart discount codes begins, but before the discount codes are updated in the Storefront API. |
113
+ | `onCreateComplete` | `() => void` | No | A callback that is invoked when the process to create a cart completes. |
114
+ | `onLineAddComplete` | `() => void` | No | A callback that is invoked when the process to add a line item to the cart completes. |
115
+ | `onLineRemoveComplete` | `() => void` | No | A callback that is invoked when the process to remove a line item to the cart completes. |
116
+ | `onLineUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update a line item in the cart completes. |
117
+ | `onNoteUpdateComplete` | `() => void` | No | A callback that is invoked when the process to add or update a note in the cart completes. |
118
+ | `onBuyerIdentityUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the buyer identity completes. |
119
+ | `onAttributesUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the cart attributes completes. |
120
+ | `onDiscountCodesUpdateComplete` | `() => void` | No | A callback that is invoked when the process to update the cart discount codes completes. |
121
+ | `data` | `PartialDeep<CartType, {recurseIntoArrays: true}>` | No | An object with fields that correspond to the Storefront API's Cart object. |
122
+ | `cartFragment` | `string` | No | A fragment used to query the Storefront API's Cart object for all queries and mutations. A default value is used if no argument is provided. |
123
+ | `customerAccessToken` | `string` | No | A customer access token that's accessible on the server if there's a customer login. |
124
+ | `countryCode` | `CountryCode` | No | The ISO country code for i18n. |
125
+
126
+ ### Override Key
127
+
128
+ If you need to pass in a different Rebuy API key from the one that we dynamically use for your store, you can pass it in as a prop on either of the provider components, e.g., `overrideApiKey="123456"`.
129
+
130
+ ---
131
+
132
+ # 🎨 Themed Styles
133
+
134
+ Rebuy provides themed stylesheets that automatically synchronize your components with the design settings configured in your Rebuy admin panel. This ensures that button colors, widget text colors, typography, spacing, and other visual elements match your brand preferences without requiring manual CSS customization.
135
+
136
+ ### For Remix/Hydrogen Users
137
+
138
+ Use the `getRebuyThemeStylesLink` function in your root layout file's `links()` function for optimal performance:
139
+
140
+ 1. Import the function in your root layout file (typically `app/root.tsx`):
141
+
142
+ ```typescript
143
+ import { getRebuyThemeStylesLink } from '@rebuy/rebuy-hydrogen';
144
+ ```
145
+
146
+ 2. Add the theme styles to your `links()` function:
147
+
148
+ ```typescript
149
+ export function links() {
150
+ const links = [
151
+ {
152
+ rel: 'preconnect',
153
+ href: 'https://cdn.shopify.com',
154
+ },
155
+ // ... other links
156
+ ];
157
+
158
+ // Add Rebuy theme styles
159
+ links.push(
160
+ ...getRebuyThemeStylesLink({
161
+ apiKey: 'your-rebuy-api-key-here',
162
+ })
163
+ );
164
+
165
+ return links;
166
+ }
167
+ ```
168
+
169
+ ### For Other Frameworks
170
+
171
+ If you're not using Remix, you can include the stylesheet directly in your HTML `<head>` or via your framework's preferred method:
172
+
173
+ ```html
174
+ <link rel="stylesheet" href="https://rebuyengine.com/api/v1/theme-styles?key=your-rebuy-api-key-here" />
175
+ ```
176
+
177
+ ### Finding Your API Key
178
+
179
+ You can find your Rebuy API key in your [Rebuy admin account settings](https://rebuyengine.com/account/keys) (login required).
180
+
181
+ ---
182
+
183
+ # 🧩 Components Reference
123
184
 
124
185
  Our components work seamlessly in both Hydrogen-only and Hydrogen React applications by using the existing context to call the correct hooks/functions.
125
186
 
@@ -129,80 +190,577 @@ This is the parent component that provides the needed context to child widgets.
129
190
 
130
191
  **Properties:**
131
192
 
132
- | Property | Description |
133
- | :---- | :---- |
134
- | `dataSource` | The Rebuy API endpoint to use for product recommendations |
135
- | `productId` | The Shopify product ID |
136
- | `product` | The entire product object |
137
- | `variantID` | The selected variant ID |
138
- | `variant` | The selected variant object |
139
- | `limit` | How many product recommendations to return |
140
- | `options` | An object with key-value pairs of Rebuy REST API arguments (e.g., `{ metafields: "yes" }`) |
193
+ | Property | Description |
194
+ | :----------- | :----------------------------------------------------------------------------------------- |
195
+ | `dataSource` | The Rebuy API endpoint to use for product recommendations |
196
+ | `productId` | The Shopify product ID |
197
+ | `product` | The entire product object |
198
+ | `variantID` | The selected variant ID |
199
+ | `variant` | The selected variant object |
200
+ | `limit` | How many product recommendations to return |
201
+ | `options` | An object with key-value pairs of Rebuy REST API arguments (e.g., `{ metafields: "yes" }`) |
141
202
 
142
203
  ### RebuyCompleteTheLook
143
204
 
144
205
  **Properties:**
145
206
 
146
- | Property | Description |
147
- | :---- | :---- |
148
- | `customTitle` | A custom title displayed above the component |
149
- | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
150
- | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
151
- | `addToCartCallBack` | A callback function for custom functionality when items are added to the cart |
152
- | `addToCartBtnText` | Custom text for the Add To Cart button |
207
+ | Property | Description |
208
+ | :------------------ | :----------------------------------------------------------------------------------------------------------------- |
209
+ | `customTitle` | A custom title displayed above the component |
210
+ | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
211
+ | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
212
+ | `addToCartCallback` | A callback function for custom functionality when items are added to the cart |
213
+ | `addToCartBtnText` | Custom text for the Add To Cart button |
153
214
 
154
215
  ### RebuyDynamicBundleProducts
155
216
 
156
217
  **Properties:**
157
218
 
158
- | Property | Description |
159
- | :---- | :---- |
160
- | `customTitle` | A custom title displayed above the component |
161
- | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
162
- | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
163
- | `addToCartCallBack` | A callback function for custom functionality when items are added to the cart |
164
- | `addToCartBtnText` | Custom text for the Add To Cart button |
219
+ | Property | Description |
220
+ | :------------------ | :----------------------------------------------------------------------------------------------------------------- |
221
+ | `customTitle` | A custom title displayed above the component |
222
+ | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
223
+ | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
224
+ | `addToCartCallback` | A callback function for custom functionality when items are added to the cart |
225
+ | `addToCartBtnText` | Custom text for the Add To Cart button |
165
226
 
166
227
  ### RebuyProductRecommendations
167
228
 
168
229
  **Properties:**
169
230
 
170
- | Property | Description |
171
- | :---- | :---- |
172
- | `customTitle` | A custom title displayed above the component |
173
- | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
174
- | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
175
- | `addToCartCallBack` | A callback function for custom functionality when items are added to the cart |
176
- | `addToCartBtnText` | Custom text for the Add To Cart button |
231
+ | Property | Description |
232
+ | :------------------ | :----------------------------------------------------------------------------------------------------------------- |
233
+ | `customTitle` | A custom title displayed above the component |
234
+ | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
235
+ | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
236
+ | `addToCartCallback` | A callback function for custom functionality when items are added to the cart |
237
+ | `addToCartBtnText` | Custom text for the Add To Cart button |
177
238
 
178
239
  ### RebuyProductAddOns
179
240
 
180
241
  **Properties:**
181
242
 
182
- | Property | Description |
183
- | :---- | :---- |
184
- | `customTitle` | A custom title displayed above the component |
185
- | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
186
- | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
187
- | `addToCartCallBack` | A callback function for custom functionality when items are added to the cart |
188
- | `addToCartBtnText` | Custom text for the Add To Cart button |
189
- | `includeMainProduct` | Option to include the product passed from the `WidgetContainer` in the add to cart functionality |
190
- | `learnMoreText` | Text displayed in a CTA that takes users to the product page |
191
- | `subtotalText` | Text that appears before the subtotal of all add-ons |
192
- | `withProductText` | Text that appears before the total if the product from `WidgetContainer` is included in the add to cart functionality |
243
+ | Property | Description |
244
+ | :------------------- | :-------------------------------------------------------------------------------------------------------------------- |
245
+ | `customTitle` | A custom title displayed above the component |
246
+ | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly) |
247
+ | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align) |
248
+ | `addToCartCallback` | A callback function for custom functionality when items are added to the cart |
249
+ | `addToCartBtnText` | Custom text for the Add To Cart button |
250
+ | `includeMainProduct` | Option to include the product passed from the `WidgetContainer` in the add to cart functionality |
251
+ | `learnMoreText` | Text displayed in a CTA that takes users to the product page |
252
+ | `subtotalText` | Text that appears before the subtotal of all add-ons |
253
+ | `withProductText` | Text that appears before the total if the product from `WidgetContainer` is included in the add to cart functionality |
193
254
 
194
255
  ### RebuyWidget
195
256
 
196
- ## Dynamic widget that can be set up to display a widget that you have created in the Rebuy Admin
257
+ Dynamic widget that can be set up to display a widget that you have created in the Rebuy Admin.
197
258
 
198
259
  **Properties:**
199
260
 
200
- | Property | Description |
201
- | :---- | :---- |
202
- | `widgetId` | The widget Id for the widget that you want to display (can be found in the Rebuy Admin) |
203
- | `addToCartCallBack` | A callback function for custom functionality when items are added to the cart |
204
- | `productId` | The Shopify product ID |
205
- | `product` | The entire product object |
206
- | `variantID` | The selected variant ID |
207
- | `variant` | The selected variant object |
208
- | `popupTriggerid` | If you have configured this to be a popup that is triggered on a button click then you need to pass the id of the element that you want to trigger the popup to appear on |
261
+ | Property | Description |
262
+ | :------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------- |
263
+ | `widgetId` | The widget ID for the widget that you want to display (can be found in the Rebuy Admin). |
264
+ | `addToCartCallback` | A callback function for custom functionality when items are added to the cart. |
265
+ | `customTitle` | A custom title displayed above the component. |
266
+ | `customTitleLevel` | Sets the initial title level (e.g., if set to `h2`, other titles in the component will adjust to `h3` accordingly). Defaults to `h2`. |
267
+ | `customTitleStyle` | An object of custom styles for the title (e.g., text color, text align). |
268
+ | `isHydrogenReact` | A boolean indicating if the application is using Hydrogen React. This helps the component use the correct hooks/functions. |
269
+ | `popupTriggerId` | If you have configured this to be a popup that is triggered on a button click, pass the ID of the element that you want to trigger the popup. |
270
+ | `product` | The entire product object. |
271
+ | `productId` | The Shopify product ID. |
272
+ | `variant` | The selected variant object. |
273
+ | `variantId` | The selected variant ID. |
274
+
275
+ ---
276
+
277
+ # 🛒 Smart Cart Guide
278
+
279
+ 🚀 **Smart Cart: Supercharge Your Shopify Cart**
280
+
281
+ Welcome to the Rebuy Smart Cart! This powerful suite of features is designed to enhance your Shopify cart experience, boost conversions, and provide seamless integration with Rebuy's personalization engine.
282
+
283
+ > **📘 Framework Compatibility Note**
284
+ >
285
+ > This documentation covers Hydrogen projects using both Remix and React Router frameworks. If you're using React Router 7 (the newer standard), ensure you're importing from the correct packages:
286
+ >
287
+ > - Use `react-router` instead of `@remix-run/react`
288
+ > - Use `@react-router/dev` instead of `@remix-run/dev`
289
+ >
290
+ > The core functionality remains the same regardless of framework choice.
291
+
292
+ > **A Note on Hydrogen Versions**
293
+ >
294
+ > The instructions and examples in this guide are tailored for Shopify Hydrogen projects built with the **Remix framework (Hydrogen v2 and later)**. File paths like `app/root.tsx` and concepts such as route `action` functions are specific to this architecture.
295
+ >
296
+ > If you are using a non-Remix Hydrogen setup or a different React framework, you will need to adapt these instructions. While the core GraphQL fragments for the cart query are reusable, your project's methods for fetching data and handling cart mutations will be different.
297
+
298
+ ## Prerequisites
299
+
300
+ Before implementing Smart Cart features, ensure your cart route can handle JSON payloads and your GraphQL queries include the necessary fields for discount and subscription functionality.
301
+
302
+ ### JSON Cart Action Support
303
+
304
+ Smart Cart components send updates as JSON payloads to your cart route. Your cart route file (e.g., `app/routes/cart.tsx` or `app/routes/($locale).cart.tsx`) must be able to parse both JSON and form data requests.
305
+
306
+ **Update your cart route's action function:**
307
+
308
+ ```typescript
309
+ export async function action({ request, context }: ActionFunctionArgs) {
310
+ const { cart } = context;
311
+
312
+ let formData;
313
+ let action;
314
+ let inputs;
315
+
316
+ const contentType = request.headers.get('Content-Type') || '';
317
+ if (contentType.includes('application/json')) {
318
+ const jsonData = (await request.json()) as { action: string; data: any };
319
+
320
+ const actionMap = {
321
+ cartLinesAdd: CartForm.ACTIONS.LinesAdd,
322
+ cartLinesUpdate: CartForm.ACTIONS.LinesUpdate,
323
+ cartLinesRemove: CartForm.ACTIONS.LinesRemove,
324
+ discountCodesUpdate: CartForm.ACTIONS.DiscountCodesUpdate,
325
+ giftCardCodesUpdate: CartForm.ACTIONS.GiftCardCodesUpdate,
326
+ buyerIdentityUpdate: CartForm.ACTIONS.BuyerIdentityUpdate,
327
+ cartAttributesUpdate: CartForm.ACTIONS.AttributesUpdateInput,
328
+ };
329
+
330
+ const actionKey = jsonData.action as string;
331
+ action = actionKey in actionMap ? actionMap[actionKey as keyof typeof actionMap] : actionKey;
332
+ inputs = jsonData.data;
333
+ } else {
334
+ formData = await request.formData();
335
+ const formInput = CartForm.getFormInput(formData);
336
+ action = formInput.action;
337
+ inputs = formInput.inputs;
338
+ }
339
+
340
+ if (!action) {
341
+ throw new Error('No action provided');
342
+ }
343
+
344
+ let status = 200;
345
+ let result: CartQueryDataReturn;
346
+
347
+ switch (action) {
348
+ case CartForm.ACTIONS.LinesAdd:
349
+ result = await cart.addLines(inputs.lines);
350
+ break;
351
+ case CartForm.ACTIONS.LinesUpdate:
352
+ result = await cart.updateLines(inputs.lines);
353
+ break;
354
+ case CartForm.ACTIONS.LinesRemove:
355
+ result = await cart.removeLines(inputs.lineIds);
356
+ break;
357
+ case CartForm.ACTIONS.DiscountCodesUpdate: {
358
+ const formDiscountCode = inputs.discountCode;
359
+ const discountCodes = (formDiscountCode ? [formDiscountCode] : []) as string[];
360
+ discountCodes.push(...(inputs.discountCodes || []));
361
+ result = await cart.updateDiscountCodes(discountCodes);
362
+ break;
363
+ }
364
+ case CartForm.ACTIONS.GiftCardCodesUpdate: {
365
+ const formGiftCardCode = inputs.giftCardCode;
366
+ const giftCardCodes = (formGiftCardCode ? [formGiftCardCode] : []) as string[];
367
+ giftCardCodes.push(...(inputs.giftCardCodes || []));
368
+ result = await cart.updateGiftCardCodes(giftCardCodes);
369
+ break;
370
+ }
371
+ case CartForm.ACTIONS.BuyerIdentityUpdate: {
372
+ result = await cart.updateBuyerIdentity({ ...inputs.buyerIdentity });
373
+ break;
374
+ }
375
+ case CartForm.ACTIONS.AttributesUpdateInput: {
376
+ result = await cart.updateAttributes(inputs.attributes || []);
377
+ break;
378
+ }
379
+ default:
380
+ throw new Error(`${action} cart action is not defined`);
381
+ }
382
+
383
+ const cartId = result?.cart?.id;
384
+ const headers = cartId ? cart.setCartId(result.cart.id) : new Headers();
385
+ const { cart: cartResult, errors, warnings } = result;
386
+
387
+ const redirectTo = formData ? (formData.get('redirectTo') ?? null) : null;
388
+ if (typeof redirectTo === 'string') {
389
+ status = 303;
390
+ headers.set('Location', redirectTo);
391
+ }
392
+
393
+ return data(
394
+ {
395
+ cart: cartResult,
396
+ errors,
397
+ warnings,
398
+ analytics: { cartId },
399
+ },
400
+ { status, headers }
401
+ );
402
+ }
403
+ ```
404
+
405
+ **Note:** Cart route file names may vary based on your project setup. Common variations include `cart.tsx`, `($locale).cart.tsx`, or `[locale].cart.tsx`.
406
+
407
+ ### Enhanced Cart Query for Smart Cart Features
408
+
409
+ To enable full discount and subscription functionality, your cart query must include specific GraphQL fields. Update your cart query fragment to include these essential fields:
410
+
411
+ ```graphql
412
+ #graphql
413
+ fragment Money on MoneyV2 {
414
+ currencyCode
415
+ amount
416
+ }
417
+
418
+ fragment CartLine on CartLine {
419
+ id
420
+ quantity
421
+ attributes {
422
+ key
423
+ value
424
+ }
425
+ cost {
426
+ totalAmount {
427
+ ...Money
428
+ }
429
+ amountPerQuantity {
430
+ ...Money
431
+ }
432
+ compareAtAmountPerQuantity {
433
+ ...Money
434
+ }
435
+ }
436
+ merchandise {
437
+ ... on ProductVariant {
438
+ id
439
+ availableForSale
440
+ compareAtPrice {
441
+ ...Money
442
+ }
443
+ price {
444
+ ...Money
445
+ }
446
+ requiresShipping
447
+ title
448
+ image {
449
+ id
450
+ url
451
+ altText
452
+ width
453
+ height
454
+ }
455
+ product {
456
+ handle
457
+ title
458
+ id
459
+ vendor
460
+ # Required for subscription functionality
461
+ requiresSellingPlan
462
+ sellingPlanGroups(first: 100) {
463
+ edges {
464
+ node {
465
+ appName
466
+ name
467
+ options {
468
+ name
469
+ values
470
+ }
471
+ sellingPlans(first: 100) {
472
+ edges {
473
+ node {
474
+ id
475
+ name
476
+ options {
477
+ name
478
+ value
479
+ }
480
+ priceAdjustments {
481
+ adjustmentValue {
482
+ ... on SellingPlanFixedAmountPriceAdjustment {
483
+ adjustmentAmount {
484
+ amount
485
+ currencyCode
486
+ }
487
+ }
488
+ ... on SellingPlanFixedPriceAdjustment {
489
+ price {
490
+ amount
491
+ currencyCode
492
+ }
493
+ }
494
+ ... on SellingPlanPercentagePriceAdjustment {
495
+ adjustmentPercentage
496
+ }
497
+ }
498
+ }
499
+ }
500
+ }
501
+ }
502
+ }
503
+ }
504
+ }
505
+ }
506
+ selectedOptions {
507
+ name
508
+ value
509
+ }
510
+ }
511
+ }
512
+ # Required for subscription functionality
513
+ sellingPlanAllocation {
514
+ sellingPlan {
515
+ id
516
+ name
517
+ }
518
+ }
519
+ }
520
+
521
+ fragment CartApiQuery on Cart {
522
+ updatedAt
523
+ id
524
+ appliedGiftCards {
525
+ lastCharacters
526
+ amountUsed {
527
+ ...Money
528
+ }
529
+ }
530
+ checkoutUrl
531
+ totalQuantity
532
+ buyerIdentity {
533
+ countryCode
534
+ customer {
535
+ id
536
+ email
537
+ firstName
538
+ lastName
539
+ displayName
540
+ }
541
+ email
542
+ phone
543
+ }
544
+ lines(first: $numCartLines) {
545
+ nodes {
546
+ ...CartLine
547
+ }
548
+ }
549
+ cost {
550
+ subtotalAmount {
551
+ ...Money
552
+ }
553
+ totalAmount {
554
+ ...Money
555
+ }
556
+ totalDutyAmount {
557
+ ...Money
558
+ }
559
+ totalTaxAmount {
560
+ ...Money
561
+ }
562
+ }
563
+ note
564
+ attributes {
565
+ key
566
+ value
567
+ }
568
+ discountCodes {
569
+ code
570
+ applicable
571
+ }
572
+ # Required for discount functionality
573
+ discountAllocations {
574
+ discountedAmount {
575
+ ...Money
576
+ }
577
+ ... on CartCodeDiscountAllocation {
578
+ code
579
+ }
580
+ ... on CartAutomaticDiscountAllocation {
581
+ title
582
+ }
583
+ }
584
+ }
585
+ ```
586
+
587
+ **Important:** After updating your cart query fragments, regenerate your Hydrogen types:
588
+
589
+ ```bash
590
+ npm run dev -- --codegen
591
+ # OR
592
+ npm run codegen
593
+ ```
594
+
595
+ This updates your `storefrontapi.generated.d.ts` file with the new TypeScript types for Smart Cart fields.
596
+
597
+ ### Using Smart Cart Apps & Custom Code
598
+
599
+ Features like **Smart Cart Apps** and **Custom Code Blocks** inject dynamic content and scripts directly into the cart. To enable these features, you must configure your Content Security Policy (CSP) and provide the nonce to the DOM.
600
+
601
+ #### Step 1: Configure Content Security Policy
602
+
603
+ Update your server entry file (typically `app/entry.server.tsx`) to include Rebuy domains and script sources:
604
+
605
+ ```typescript
606
+ import type {AppLoadContext} from '@shopify/remix-oxygen';
607
+ import {ServerRouter} from 'react-router';
608
+ import {isbot} from 'isbot';
609
+ import {renderToReadableStream} from 'react-dom/server';
610
+ import {createContentSecurityPolicy} from '@shopify/hydrogen';
611
+ import type {EntryContext} from 'react-router';
612
+
613
+ export default async function handleRequest(
614
+ request: Request,
615
+ responseStatusCode: number,
616
+ responseHeaders: Headers,
617
+ reactRouterContext: EntryContext,
618
+ context: AppLoadContext,
619
+ ) {
620
+ const {nonce, header, NonceProvider} = createContentSecurityPolicy({
621
+ shop: {
622
+ checkoutDomain: context.env.PUBLIC_CHECKOUT_DOMAIN,
623
+ storeDomain: context.env.PUBLIC_STORE_DOMAIN,
624
+ },
625
+ scriptSrc: [
626
+ "'self'",
627
+ 'https://cdn.shopify.com',
628
+ '*.rebuyengine.com',
629
+ 'rebuyengine.com',
630
+ ],
631
+ styleSrc: [
632
+ "'self'",
633
+ 'https://cdn.shopify.com',
634
+ '*.rebuyengine.com',
635
+ 'rebuyengine.com',
636
+ ],
637
+ connectSrc: [
638
+ "'self'",
639
+ '*.rebuyengine.com',
640
+ 'rebuyengine.com',
641
+ 'https://monorail-edge.shopifysvc.com',
642
+ ],
643
+ imgSrc: ["'self'", "data:", "https://cdn.shopify.com", "*.rebuyengine.com"],
644
+ fontSrc: ["'self'", "data:", "https://cdn.shopify.com"],
645
+ });
646
+
647
+ const body = await renderToReadableStream(
648
+ <NonceProvider>
649
+ <ServerRouter
650
+ context={reactRouterContext}
651
+ url={request.url}
652
+ nonce={nonce}
653
+ />
654
+ </NonceProvider>,
655
+ {
656
+ nonce,
657
+ signal: request.signal,
658
+ onError(error) {
659
+ console.error(error);
660
+ responseStatusCode = 500;
661
+ },
662
+ },
663
+ );
664
+
665
+ if (isbot(request.headers.get('user-agent'))) {
666
+ await body.allReady;
667
+ }
668
+
669
+ responseHeaders.set('Content-Type', 'text/html');
670
+ responseHeaders.set('Content-Security-Policy', header);
671
+
672
+ return new Response(body, {
673
+ headers: responseHeaders,
674
+ status: responseStatusCode,
675
+ });
676
+ }
677
+ ```
678
+
679
+ #### Step 2: Provide Nonce to DOM
680
+
681
+ Update your root layout file (typically `app/root.tsx`) to attach the nonce to the body element:
682
+
683
+ ```tsx
684
+ import { useNonce } from '@shopify/hydrogen';
685
+
686
+ export function Layout({ children }: { children?: React.ReactNode }) {
687
+ const nonce = useNonce();
688
+
689
+ return (
690
+ <html lang="en">
691
+ <head>{/* ... */}</head>
692
+ <body data-nonce={nonce} suppressHydrationWarning>
693
+ {/* ... your providers and app content ... */}
694
+ </body>
695
+ </html>
696
+ );
697
+ }
698
+ ```
699
+
700
+ ### Login Button
701
+
702
+ The Login Button component provides a link to your store's login page and automatically hides when a customer is logged in. Configure the login URL in your Rebuy admin (defaults to `/account/login`).
703
+
704
+ ---
705
+
706
+ ## 🔧 Troubleshooting
707
+
708
+ ### GraphQL Type Errors
709
+
710
+ If you encounter TypeScript errors after updating fragments:
711
+
712
+ 1. Run the codegen command: `npm run codegen`
713
+ 2. Restart your development server
714
+ 3. Verify `storefrontapi.generated.d.ts` has been updated
715
+
716
+ ### Cart Route Issues
717
+
718
+ If Smart Cart features aren't working:
719
+
720
+ 1. Verify your cart route handles JSON payloads
721
+ 2. Check your cart route file name matches your project structure
722
+ 3. Ensure your action function processes both JSON and FormData requests
723
+
724
+ ### CSP Issues
725
+
726
+ If Smart Cart Apps or Custom Code Blocks aren't working:
727
+
728
+ 1. Verify Rebuy domains are in your CSP configuration
729
+ 2. Ensure the nonce is set on the `<body>` element
730
+ 3. Check browser console for CSP violation errors
731
+
732
+ ---
733
+
734
+ ## 📋 Compatibility
735
+
736
+ ### Hydrogen Versions
737
+
738
+ - ✅ Hydrogen 2025.5.0+
739
+ - ✅ React Router 7.x
740
+ - ✅ Remix-based Hydrogen projects
741
+ - ✅ Hydrogen React 2.0+
742
+
743
+ ### Node.js Requirements
744
+
745
+ - Node.js 18.0.0 or higher
746
+ - npm 8.0.0 or higher
747
+
748
+ ### Framework Support
749
+
750
+ - **Remix Framework**: Full support
751
+ - **React Router 7**: Full support
752
+ - **Hydrogen React**: Enhanced cart provider with additional props
753
+
754
+ ### Browser Support
755
+
756
+ - Chrome 90+
757
+ - Firefox 88+
758
+ - Safari 14+
759
+ - Edge 90+
760
+
761
+ ### Shopify Compatibility
762
+
763
+ - Storefront API 2024-01+
764
+ - Checkout API compatibility
765
+ - Multi-language/locale support
766
+ - Customer account integration