@liquidcommerce/elements-sdk 2.6.0-beta.9 → 2.6.0-beta.90

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 (225) hide show
  1. package/README.md +84 -2520
  2. package/dist/index.checkout.esm.js +16940 -0
  3. package/dist/index.esm.js +24189 -20939
  4. package/dist/ssr-stub.checkout.esm.js +18 -0
  5. package/dist/ssr-stub.esm.js +270 -0
  6. package/dist/types/auto-initialize/checkout.d.ts +2 -0
  7. package/dist/types/auto-initialize/shared-utils.d.ts +50 -0
  8. package/dist/types/{elements-base-client.d.ts → clients/base.d.ts} +15 -2
  9. package/dist/types/clients/builder.d.ts +3 -0
  10. package/dist/types/clients/checkout.d.ts +6 -0
  11. package/dist/types/{elements-client-helper.d.ts → clients/helpers.d.ts} +2 -1
  12. package/dist/types/clients/main.d.ts +3 -0
  13. package/dist/types/constants/core.constant.d.ts +2 -6
  14. package/dist/types/core/api/api-client.service.d.ts +20 -18
  15. package/dist/types/core/api/api-result.d.ts +19 -0
  16. package/dist/types/core/api/auth-client.service.d.ts +37 -13
  17. package/dist/types/core/api/http-client.service.d.ts +0 -8
  18. package/dist/types/core/base-component.service.d.ts +2 -1
  19. package/dist/types/core/client/actions/base-action.service.d.ts +22 -0
  20. package/dist/types/core/client/actions/client-address-action.service.d.ts +18 -0
  21. package/dist/types/core/client/actions/client-cart-action.service.d.ts +38 -0
  22. package/dist/types/core/client/actions/client-checkout-action.service.d.ts +69 -0
  23. package/dist/types/core/client/actions/client-product-action.service.d.ts +15 -0
  24. package/dist/types/core/client/client-action.service.d.ts +6 -74
  25. package/dist/types/core/client/client-config.service.d.ts +8 -5
  26. package/dist/types/core/google-tag-manager.service.d.ts +2 -1
  27. package/dist/types/core/logger/logger.service.d.ts +1 -1
  28. package/dist/types/core/pubsub/interfaces/address.interface.d.ts +3 -0
  29. package/dist/types/core/pubsub/interfaces/cart.interface.d.ts +1 -1
  30. package/dist/types/core/pubsub/interfaces/checkout.interface.d.ts +36 -51
  31. package/dist/types/core/pubsub/interfaces/core.interface.d.ts +11 -6
  32. package/dist/types/core/pubsub/pubsub.service.d.ts +1 -2
  33. package/dist/types/core/singleton-manager.service.d.ts +12 -8
  34. package/dist/types/core/store/interfaces/cart.interface.d.ts +2 -3
  35. package/dist/types/core/store/interfaces/checkout.interface.d.ts +18 -108
  36. package/dist/types/core/store/interfaces/core.interface.d.ts +12 -2
  37. package/dist/types/core/store/interfaces/metadata.interface.d.ts +11 -0
  38. package/dist/types/core/store/interfaces/product-list.interface.d.ts +30 -0
  39. package/dist/types/core/store/interfaces/product.interface.d.ts +1 -0
  40. package/dist/types/core/store/store.constant.d.ts +5 -0
  41. package/dist/types/core/store/store.service.d.ts +1 -0
  42. package/dist/types/core/telemetry/telemetry.service.d.ts +1 -0
  43. package/dist/types/enums/core.enum.d.ts +39 -1
  44. package/dist/types/enums/index.d.ts +0 -1
  45. package/dist/types/index.checkout.d.ts +8 -0
  46. package/dist/types/index.checkout.umd.d.ts +4 -0
  47. package/dist/types/index.d.ts +8 -3
  48. package/dist/types/interfaces/api/cart.interface.d.ts +12 -7
  49. package/dist/types/interfaces/api/checkout.interface.d.ts +239 -0
  50. package/dist/types/interfaces/api/index.d.ts +5 -0
  51. package/dist/types/interfaces/api/product-list.interface.d.ts +39 -0
  52. package/dist/types/interfaces/api/product.interface.d.ts +10 -4
  53. package/dist/types/interfaces/client.interface.d.ts +72 -0
  54. package/dist/types/interfaces/component.interface.d.ts +7 -0
  55. package/dist/types/interfaces/config.interface.d.ts +40 -0
  56. package/dist/types/interfaces/configs/address.interface.d.ts +1 -1
  57. package/dist/types/interfaces/configs/cart.interface.d.ts +1 -1
  58. package/dist/types/interfaces/configs/checkout.interface.d.ts +2 -1
  59. package/dist/types/interfaces/configs/global.interface.d.ts +5 -3
  60. package/dist/types/interfaces/configs/index.d.ts +1 -0
  61. package/dist/types/interfaces/configs/product-list.interface.d.ts +49 -0
  62. package/dist/types/interfaces/configs/product.interface.d.ts +3 -1
  63. package/dist/types/interfaces/injection.interface.d.ts +49 -0
  64. package/dist/types/modules/address/address.command.d.ts +2 -1
  65. package/dist/types/modules/address/styles/register-styles.d.ts +1 -0
  66. package/dist/types/modules/cart/cart.commands.d.ts +4 -4
  67. package/dist/types/modules/cart/styles/register-styles.d.ts +1 -0
  68. package/dist/types/modules/checkout/checkout.commands.d.ts +26 -10
  69. package/dist/types/modules/checkout/checkout.component.d.ts +2 -0
  70. package/dist/types/modules/checkout/components/checkout-billing.component.d.ts +2 -2
  71. package/dist/types/modules/checkout/components/checkout-completed.component.d.ts +3 -0
  72. package/dist/types/modules/checkout/components/checkout-header.component.d.ts +1 -0
  73. package/dist/types/modules/checkout/components/checkout-item-quantity.component.d.ts +3 -0
  74. package/dist/types/modules/checkout/components/checkout-items.component.d.ts +4 -3
  75. package/dist/types/modules/checkout/components/checkout-payment.component.d.ts +1 -1
  76. package/dist/types/modules/checkout/components/checkout-presale-countdown.component.d.ts +14 -1
  77. package/dist/types/modules/checkout/components/checkout-presale-expired.component.d.ts +7 -1
  78. package/dist/types/modules/checkout/components/checkout-stripe-form.component.d.ts +2 -1
  79. package/dist/types/modules/checkout/components/checkout-tips.component.d.ts +2 -2
  80. package/dist/types/modules/checkout/components/promo-pc-gc.component.d.ts +0 -2
  81. package/dist/types/modules/checkout/constant.d.ts +3 -0
  82. package/dist/types/modules/checkout/styles/register-styles.d.ts +1 -0
  83. package/dist/types/modules/product/components/product-add-to-cart-section.component.d.ts +1 -0
  84. package/dist/types/modules/product/components/product-description.component.d.ts +1 -0
  85. package/dist/types/modules/product/components/product-image-carousel.component.d.ts +3 -0
  86. package/dist/types/modules/product/components/product-options.component.d.ts +2 -1
  87. package/dist/types/modules/product/components/product-retailers-carousel.component.d.ts +3 -0
  88. package/dist/types/modules/product/components/product-retailers-popup-list.component.d.ts +5 -2
  89. package/dist/types/modules/product/product.commands.d.ts +3 -3
  90. package/dist/types/modules/product/styles/register-styles.d.ts +1 -0
  91. package/dist/types/modules/product-list/components/card-components/index.d.ts +5 -0
  92. package/dist/types/modules/product-list/components/card-components/product-badge.d.ts +9 -0
  93. package/dist/types/modules/product-list/components/card-components/product-button.d.ts +11 -0
  94. package/dist/types/modules/product-list/components/card-components/product-price-and-personalization.d.ts +13 -0
  95. package/dist/types/modules/product-list/components/card-components/product-quantity-selector.d.ts +10 -0
  96. package/dist/types/modules/product-list/components/card-components/product-sizes-list.d.ts +13 -0
  97. package/dist/types/modules/product-list/components/filter-components/index.d.ts +7 -0
  98. package/dist/types/modules/product-list/components/filter-components/product-list-apply-filter-button.d.ts +1 -0
  99. package/dist/types/modules/product-list/components/filter-components/product-list-chip.d.ts +5 -0
  100. package/dist/types/modules/product-list/components/filter-components/product-list-filters-chips.d.ts +13 -0
  101. package/dist/types/modules/product-list/components/filter-components/product-list-fulfillment-filter.d.ts +14 -0
  102. package/dist/types/modules/product-list/components/{product-list-filters-subcomponents/product-list-price-filter.components.d.ts → filter-components/product-list-price-filter.d.ts} +1 -1
  103. package/dist/types/modules/product-list/components/filter-components/product-list-toggle-filters.d.ts +7 -0
  104. package/dist/types/modules/product-list/components/index.d.ts +6 -2
  105. package/dist/types/modules/product-list/components/product-list-card-loading.component.d.ts +3 -1
  106. package/dist/types/modules/product-list/components/product-list-card.component.d.ts +39 -31
  107. package/dist/types/modules/product-list/components/product-list-engraving.component.d.ts +12 -0
  108. package/dist/types/modules/product-list/components/product-list-filters.component.d.ts +55 -36
  109. package/dist/types/modules/product-list/components/product-list-product-engraving-lines.component.d.ts +22 -0
  110. package/dist/types/modules/product-list/components/product-list-product-pre-cart.component.d.ts +50 -0
  111. package/dist/types/modules/product-list/components/product-list-search.component.d.ts +25 -0
  112. package/dist/types/modules/product-list/product-list-filter.utils.d.ts +8 -0
  113. package/dist/types/modules/product-list/product-list-query-params.utils.d.ts +3 -0
  114. package/dist/types/modules/product-list/product-list.commands.d.ts +23 -8
  115. package/dist/types/modules/product-list/product-list.component.d.ts +14 -47
  116. package/dist/types/modules/product-list/product-list.constants.d.ts +38 -0
  117. package/dist/types/modules/product-list/product-list.interface.d.ts +20 -35
  118. package/dist/types/modules/product-list/styles/product-list-card.style.d.ts +1 -0
  119. package/dist/types/modules/product-list/styles/product-list-filters.style.d.ts +1 -0
  120. package/dist/types/modules/product-list/styles/register-styles.d.ts +1 -0
  121. package/dist/types/modules/theme-provider/constants/component-groupings.d.ts +1 -0
  122. package/dist/types/modules/theme-provider/constants/css-variable-mappings.d.ts +1 -1
  123. package/dist/types/modules/theme-provider/services/style-registry.service.d.ts +16 -0
  124. package/dist/types/modules/theme-provider/services/stylesheet-generator.service.d.ts +0 -1
  125. package/dist/types/modules/theme-provider/styles/register-styles.d.ts +1 -0
  126. package/dist/types/modules/theme-provider/theme-provider.service.d.ts +2 -2
  127. package/dist/types/modules/ui-components/drawer/drawer.component.d.ts +1 -0
  128. package/dist/types/modules/ui-components/engraving/engraving-form.component.d.ts +6 -1
  129. package/dist/types/modules/ui-components/engraving/engraving-view.component.d.ts +6 -1
  130. package/dist/types/modules/ui-components/input/index.d.ts +0 -1
  131. package/dist/types/modules/ui-components/input/input.component.d.ts +8 -1
  132. package/dist/types/modules/ui-components/lce-element/lce-element.component.d.ts +2 -1
  133. package/dist/types/modules/ui-components/promo-code-ticker/promo-code-ticker.component.d.ts +1 -1
  134. package/dist/types/modules/ui-components/ui.commands.d.ts +5 -1
  135. package/dist/types/ssr/stub.checkout.d.ts +6 -0
  136. package/dist/types/ssr/stub.d.ts +10 -0
  137. package/dist/types/static/icon/check.icon.d.ts +2 -0
  138. package/dist/types/static/icon/index.d.ts +1 -0
  139. package/dist/types/utils/dom-compat.d.ts +2 -0
  140. package/dist/types/utils/format.d.ts +0 -14
  141. package/dist/types/utils/product-selection.d.ts +16 -0
  142. package/dist/types/utils/product.d.ts +15 -0
  143. package/docs/v1/README.md +210 -0
  144. package/docs/v1/api/actions/address-actions.md +286 -0
  145. package/docs/v1/api/actions/cart-actions.md +357 -0
  146. package/docs/v1/api/actions/checkout-actions.md +525 -0
  147. package/docs/v1/api/actions/product-actions.md +204 -0
  148. package/docs/v1/api/client.md +517 -0
  149. package/docs/v1/api/configuration.md +532 -0
  150. package/docs/v1/api/injection-methods.md +292 -0
  151. package/docs/v1/api/typescript-types.md +419 -0
  152. package/docs/v1/api/ui-helpers.md +200 -0
  153. package/docs/v1/examples/advanced-patterns.md +199 -0
  154. package/docs/v1/examples/checkout-flow.md +90 -0
  155. package/docs/v1/examples/custom-theming.md +63 -0
  156. package/docs/v1/examples/multi-product-page.md +90 -0
  157. package/docs/v1/examples/simple-product-page.md +89 -0
  158. package/docs/v1/getting-started/concepts.md +502 -0
  159. package/docs/v1/getting-started/installation.md +328 -0
  160. package/docs/v1/getting-started/quick-start.md +405 -0
  161. package/docs/v1/guides/address-component.md +435 -0
  162. package/docs/v1/guides/best-practices.md +365 -0
  163. package/docs/v1/guides/cart-component.md +725 -0
  164. package/docs/v1/guides/checkout-component.md +670 -0
  165. package/docs/v1/guides/events.md +926 -0
  166. package/docs/v1/guides/product-component.md +731 -0
  167. package/docs/v1/guides/product-list-component.md +631 -0
  168. package/docs/v1/guides/theming.md +213 -0
  169. package/docs/v1/integration/angular.md +39 -0
  170. package/docs/v1/integration/laravel.md +41 -0
  171. package/docs/v1/integration/nextjs.md +69 -0
  172. package/docs/v1/integration/proxy-setup.md +106 -0
  173. package/docs/v1/integration/react.md +64 -0
  174. package/docs/v1/integration/vanilla-js.md +84 -0
  175. package/docs/v1/integration/vue.md +58 -0
  176. package/docs/v1/reference/browser-support.md +45 -0
  177. package/docs/v1/reference/error-handling.md +75 -0
  178. package/docs/v1/reference/performance.md +52 -0
  179. package/docs/v1/reference/troubleshooting.md +136 -0
  180. package/package.json +33 -37
  181. package/dist/types/elements-builder-client.d.ts +0 -2
  182. package/dist/types/elements-client.d.ts +0 -2
  183. package/dist/types/enums/cloud.enum.d.ts +0 -106
  184. package/dist/types/interfaces/cloud/catalog.interface.d.ts +0 -42
  185. package/dist/types/interfaces/cloud/checkout.interface.d.ts +0 -218
  186. package/dist/types/interfaces/cloud/core.interface.d.ts +0 -22
  187. package/dist/types/interfaces/cloud/index.d.ts +0 -4
  188. package/dist/types/interfaces/cloud/retailer.interface.d.ts +0 -67
  189. package/dist/types/interfaces/cloud/user.interface.d.ts +0 -100
  190. package/dist/types/interfaces/core.interface.d.ts +0 -111
  191. package/dist/types/modules/checkout/components/checkout.type.d.ts +0 -4
  192. package/dist/types/modules/product-list/components/product-list-filters-subcomponents/index.d.ts +0 -6
  193. package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-apply-filter-button.component.d.ts +0 -1
  194. package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-delivery-options-filter.components.d.ts +0 -16
  195. package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-search.component.d.ts +0 -16
  196. package/dist/types/modules/product-list/components/product-list-filters-subcomponents/product-list-toggle-filters.components.d.ts +0 -18
  197. package/dist/types/modules/theme-provider/styles/address/index.d.ts +0 -1
  198. package/dist/types/modules/theme-provider/styles/cart/index.d.ts +0 -1
  199. package/dist/types/modules/theme-provider/styles/checkout/index.d.ts +0 -1
  200. package/dist/types/modules/theme-provider/styles/product/index.d.ts +0 -3
  201. package/dist/types/modules/theme-provider/styles/product-list/index.d.ts +0 -1
  202. package/dist/types/modules/theme-provider/styles/ui/index.d.ts +0 -3
  203. package/dist/types/modules/ui-components/input/birthdate-input.component.d.ts +0 -53
  204. package/dist/types/utils/helper.d.ts +0 -28
  205. package/docs/ACTIONS.md +0 -1300
  206. package/docs/BROWSER_SUPPORT.md +0 -279
  207. package/docs/CONFIGURATION.md +0 -853
  208. package/docs/DOCUMENTATION_INDEX.md +0 -311
  209. package/docs/EVENTS.md +0 -798
  210. package/docs/PROXY.md +0 -228
  211. package/docs/THEMING.md +0 -592
  212. package/docs/TROUBLESHOOTING.md +0 -793
  213. package/umd/elements.js +0 -1
  214. /package/dist/types/{auto-initialize.d.ts → auto-initialize/main.d.ts} +0 -0
  215. /package/dist/types/modules/{theme-provider/styles/address → address/styles}/address.style.d.ts +0 -0
  216. /package/dist/types/modules/{theme-provider/styles/cart → cart/styles}/cart.style.d.ts +0 -0
  217. /package/dist/types/modules/{theme-provider/styles/checkout → checkout/styles}/checkout.style.d.ts +0 -0
  218. /package/dist/types/modules/{theme-provider/styles/product → product/styles}/image-carousel.style.d.ts +0 -0
  219. /package/dist/types/modules/{theme-provider/styles/product → product/styles}/product.style.d.ts +0 -0
  220. /package/dist/types/modules/{theme-provider/styles/product → product/styles}/retailers.style.d.ts +0 -0
  221. /package/dist/types/modules/product-list/components/{product-list-filters-subcomponents/product-list-checkbox-filter.components.d.ts → filter-components/product-list-checkbox-filter.d.ts} +0 -0
  222. /package/dist/types/modules/{theme-provider/styles/product-list → product-list/styles}/product-list.style.d.ts +0 -0
  223. /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/drawer.style.d.ts +0 -0
  224. /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/loading.style.d.ts +0 -0
  225. /package/dist/types/modules/{theme-provider/styles/ui → ui-components/styles}/promo-code-ticker.style.d.ts +0 -0
@@ -0,0 +1,365 @@
1
+ # Best Practices
2
+
3
+ Recommended patterns and practices for working with the Elements SDK.
4
+
5
+ ## Initialization
6
+
7
+ ### Initialize Once
8
+
9
+ Create a single client instance and reuse it:
10
+
11
+ ```javascript
12
+ // Good
13
+ const client = await Elements('KEY', { env: 'production' });
14
+ await client.injectProductElement([...]);
15
+ await client.injectCartElement('cart');
16
+
17
+ // Bad - creates multiple instances
18
+ await Elements('KEY', { env: 'production' });
19
+ await Elements('KEY', { env: 'production' });
20
+ ```
21
+
22
+ ### Use Global Access
23
+
24
+ After initialization, use `window.LiquidCommerce.elements`:
25
+
26
+ ```javascript
27
+ // Initialize once
28
+ await Elements('KEY', { env: 'production' });
29
+
30
+ // Use globally throughout your app
31
+ window.LiquidCommerce.elements.actions.cart.openCart();
32
+ ```
33
+
34
+ ### Wait for Client Ready
35
+
36
+ ```javascript
37
+ if (window.LiquidCommerce.elements) {
38
+ // Client already ready
39
+ window.LiquidCommerce.elements.actions.cart.openCart();
40
+ } else {
41
+ // Wait for initialization
42
+ window.addEventListener('lce:actions.client_ready', () => {
43
+ window.LiquidCommerce.elements.actions.cart.openCart();
44
+ });
45
+ }
46
+ ```
47
+
48
+ ## Component Injection
49
+
50
+ ### Verify Container Exists
51
+
52
+ ```javascript
53
+ // Check container before injection
54
+ if (document.getElementById('product')) {
55
+ await client.injectProductElement([
56
+ { containerId: 'product', identifier: '123' }
57
+ ]);
58
+ }
59
+ ```
60
+
61
+ ### Provide Adequate Space
62
+
63
+ ```css
64
+ #product-container {
65
+ min-height: 600px; /* Prevent layout shift */
66
+ max-width: 1200px;
67
+ }
68
+ ```
69
+
70
+ ### Handle Loading States
71
+
72
+ ```javascript
73
+ showLoader('product-container');
74
+
75
+ await client.injectProductElement([...]);
76
+
77
+ // Loader automatically replaced when product loads
78
+ ```
79
+
80
+ ## Error Handling
81
+
82
+ ### Catch Errors Appropriately
83
+
84
+ ```javascript
85
+ try {
86
+ await window.LiquidCommerce.elements.actions.cart.addProduct([...]);
87
+ } catch (error) {
88
+ if (error.name === 'SDKError') {
89
+ console.error('SDK Error:', error);
90
+ }
91
+ }
92
+ ```
93
+
94
+ ### Provide Fallbacks
95
+
96
+ ```javascript
97
+ const client = await Elements('KEY', { env: 'production' });
98
+
99
+ if (!client) {
100
+ // Initialization failed
101
+ showFallbackUI();
102
+ return;
103
+ }
104
+ ```
105
+
106
+ ## Performance
107
+
108
+ ### Lazy Load Products
109
+
110
+ ```javascript
111
+ const observer = new IntersectionObserver(async (entries) => {
112
+ for (const entry of entries) {
113
+ if (entry.isIntersecting) {
114
+ const container = entry.target;
115
+ await client.injectProductElement([
116
+ { containerId: container.id, identifier: container.dataset.productId }
117
+ ]);
118
+ observer.unobserve(container);
119
+ }
120
+ }
121
+ });
122
+
123
+ document.querySelectorAll('.product-placeholder').forEach(el => {
124
+ observer.observe(el);
125
+ });
126
+ ```
127
+
128
+ ### Use Checkout-Only Build
129
+
130
+ For checkout pages:
131
+
132
+ ```javascript
133
+ import { ElementsCheckout } from '@liquidcommerce/elements-sdk/checkout';
134
+ ```
135
+
136
+ Reduces bundle size by ~60%.
137
+
138
+ ### Defer Non-Critical Operations
139
+
140
+ ```javascript
141
+ // Load visible products first
142
+ await client.injectProductElement([
143
+ { containerId: 'hero-product', identifier: '001' }
144
+ ]);
145
+
146
+ // Load others after delay
147
+ setTimeout(async () => {
148
+ await client.injectProductElement([
149
+ { containerId: 'related-1', identifier: '002' }
150
+ ]);
151
+ }, 1000);
152
+ ```
153
+
154
+ ## State Management
155
+
156
+ ### Pre-fill Known Data
157
+
158
+ ```javascript
159
+ // Set address if known
160
+ if (userSavedAddress) {
161
+ await window.LiquidCommerce.elements.actions.address.setAddressManually(
162
+ userSavedAddress,
163
+ userCoordinates
164
+ );
165
+ }
166
+
167
+ // Pre-fill checkout info
168
+ window.addEventListener('lce:actions.checkout_opened', () => {
169
+ if (userIsLoggedIn) {
170
+ window.LiquidCommerce.elements.actions.checkout.updateCustomerInfo({
171
+ firstName: user.firstName,
172
+ email: user.email
173
+ });
174
+ }
175
+ });
176
+ ```
177
+
178
+ ### Don't Clear Cart Unnecessarily
179
+
180
+ Cart persists across sessions - avoid clearing unless intentional:
181
+
182
+ ```javascript
183
+ // Only clear when user explicitly requests
184
+ document.getElementById('clear-cart-btn').addEventListener('click', async () => {
185
+ if (confirm('Clear cart?')) {
186
+ await window.LiquidCommerce.elements.actions.cart.resetCart();
187
+ }
188
+ });
189
+ ```
190
+
191
+ ## Cleanup
192
+
193
+ ### Destroy Components When Done
194
+
195
+ In single-page applications, clean up when navigating away:
196
+
197
+ ```javascript
198
+ // Destroy individual component
199
+ const component = client.getInjectedComponents().get('product-1');
200
+ component?.destroy();
201
+
202
+ // Destroy entire client (on route change)
203
+ client.destroy();
204
+ ```
205
+
206
+ ### Avoid Leaking References
207
+
208
+ ```javascript
209
+ // Good - clean up on unmount
210
+ useEffect(() => {
211
+ const init = async () => {
212
+ const c = await Elements('KEY', { env: 'production' });
213
+ clientRef.current = c;
214
+ };
215
+ init();
216
+ return () => clientRef.current?.destroy();
217
+ }, []);
218
+ ```
219
+
220
+ ## Events
221
+
222
+ ### Use Events for Reactive Updates
223
+
224
+ ```javascript
225
+ // Update UI when cart changes
226
+ window.addEventListener('lce:actions.cart_updated', () => {
227
+ const cart = window.LiquidCommerce.elements.actions.cart.getDetails();
228
+ updateHeaderCartCount(cart.itemCount);
229
+ });
230
+ ```
231
+
232
+ ### Track Important Events
233
+
234
+ ```javascript
235
+ window.addEventListener('lce:actions.checkout_submit_completed', (event) => {
236
+ const { orderNumber, orderTotal } = event.detail.data;
237
+
238
+ // Analytics
239
+ gtag('event', 'purchase', {
240
+ transaction_id: orderNumber,
241
+ value: orderTotal / 100
242
+ });
243
+
244
+ // Backend tracking
245
+ fetch('/api/track-order', {
246
+ method: 'POST',
247
+ body: JSON.stringify({ orderNumber, orderTotal })
248
+ });
249
+ });
250
+ ```
251
+
252
+ ## Security
253
+
254
+ ### Use Proxy in Production
255
+
256
+ ```javascript
257
+ const client = await Elements('YOUR_API_KEY', {
258
+ env: 'production',
259
+ proxy: {
260
+ baseUrl: 'https://yoursite.com/api/elements-proxy'
261
+ }
262
+ });
263
+ ```
264
+
265
+ Prevents ad blockers and protects API keys.
266
+
267
+ ### Separate API Keys by Environment
268
+
269
+ ```javascript
270
+ const apiKey = process.env.NODE_ENV === 'production'
271
+ ? 'prod_key_xyz'
272
+ : 'dev_key_abc';
273
+
274
+ const client = await Elements(apiKey, {
275
+ env: process.env.NODE_ENV === 'production' ? 'production' : 'development'
276
+ });
277
+ ```
278
+
279
+ ## Testing
280
+
281
+ ### Use Development Mode
282
+
283
+ ```javascript
284
+ const client = await Elements('YOUR_API_KEY', {
285
+ env: 'development',
286
+ debugMode: 'console', // or 'panel'
287
+ development: {
288
+ openShadowDom: true // Makes debugging easier
289
+ }
290
+ });
291
+ ```
292
+
293
+ ### Skip card entry in checkout tests
294
+
295
+ Pre-select a saved payment method so the checkout payment step shows a read-only summary and never mounts the Stripe card form. Pass a payment method id the backend already has for the checkout's customer:
296
+
297
+ ```javascript
298
+ window.LiquidCommerce.elements.actions.checkout.setSavedPaymentMethod({
299
+ id: 'pm_123',
300
+ card: { brand: 'Visa', last4: '4242', expMonth: '12', expYear: '30' }
301
+ });
302
+ ```
303
+
304
+ `setSavedPaymentMethod` is a production action (also exposed on the checkout-only client), not test-only — beyond tests, use it to pre-fill a returning shopper's saved card. See [Checkout Actions](../api/actions/checkout-actions.md#actionscheckoutsetsavedpaymentmethod).
305
+
306
+ ### Handle Test Scenarios
307
+
308
+ ```javascript
309
+ // Test empty cart
310
+ if (isDevelopment) {
311
+ await window.LiquidCommerce.elements.actions.cart.resetCart();
312
+ }
313
+
314
+ // Test with specific product
315
+ await window.LiquidCommerce.elements.actions.cart.addProduct([
316
+ { identifier: testProductId, fulfillmentType: 'shipping', quantity: 1 }
317
+ ]);
318
+ ```
319
+
320
+ ## Accessibility
321
+
322
+ ### Provide Labels
323
+
324
+ ```html
325
+ <label for="cart-toggle">Shopping Cart</label>
326
+ <button id="cart-toggle" data-lce-cart-toggle-button>
327
+ Cart (<span data-lce-cart-items-count></span>)
328
+ </button>
329
+ ```
330
+
331
+ ### Use Semantic HTML
332
+
333
+ ```html
334
+ <nav aria-label="Main navigation">
335
+ <div id="cart-button"></div>
336
+ </nav>
337
+ ```
338
+
339
+ ## Mobile Optimization
340
+
341
+ ### Responsive Containers
342
+
343
+ ```css
344
+ @media (max-width: 768px) {
345
+ #product-container {
346
+ padding: 10px;
347
+ }
348
+ }
349
+ ```
350
+
351
+ ### Mobile-Specific Cart Button
352
+
353
+ ```javascript
354
+ if (window.innerWidth < 768) {
355
+ window.LiquidCommerce.elements.ui.floatingCartButton(true);
356
+ } else {
357
+ window.LiquidCommerce.elements.ui.cartButton('header-cart', true);
358
+ }
359
+ ```
360
+
361
+ ## See Also
362
+
363
+ - [Performance Guide](../reference/performance.md)
364
+ - [Troubleshooting](../reference/troubleshooting.md)
365
+ - [Component Guides](../guides/)