@shopify/hydrogen 2026.10.0-preview.4 → 2026.10.0

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 (437) hide show
  1. package/dist/cli/index.mjs +23 -12
  2. package/dist/client/client.d.mts +18 -15
  3. package/dist/client/client.mjs +8 -3
  4. package/dist/client/client.mjs.map +1 -1
  5. package/dist/client/errors.d.mts +35 -13
  6. package/dist/client/errors.mjs +23 -13
  7. package/dist/client/errors.mjs.map +1 -1
  8. package/dist/client/types.d.mts +140 -90
  9. package/dist/core/analytics/cart-tracker.d.mts +19 -10
  10. package/dist/core/analytics/cart-tracker.mjs +18 -10
  11. package/dist/core/analytics/cart-tracker.mjs.map +1 -1
  12. package/dist/core/analytics/events.d.mts +17 -11
  13. package/dist/core/analytics/events.mjs +13 -4
  14. package/dist/core/analytics/events.mjs.map +1 -1
  15. package/dist/core/analytics/types.d.mts +207 -118
  16. package/dist/core/analytics/utils/flatten-connection.d.mts +11 -9
  17. package/dist/core/analytics/utils/flatten-connection.mjs +7 -6
  18. package/dist/core/analytics/utils/flatten-connection.mjs.map +1 -1
  19. package/dist/core/cache/fetch-with-cache.d.mts +24 -4
  20. package/dist/core/cache/fetch-with-cache.mjs +17 -2
  21. package/dist/core/cache/fetch-with-cache.mjs.map +1 -1
  22. package/dist/core/cache/key.d.mts +2 -0
  23. package/dist/core/cache/key.mjs.map +1 -1
  24. package/dist/core/cache/run-with-cache.d.mts +56 -8
  25. package/dist/core/cache/run-with-cache.mjs +17 -6
  26. package/dist/core/cache/run-with-cache.mjs.map +1 -1
  27. package/dist/core/cache/store.d.mts +8 -6
  28. package/dist/core/cache/store.mjs.map +1 -1
  29. package/dist/core/cache/strategies.d.mts +27 -2
  30. package/dist/core/cache/strategies.mjs +6 -0
  31. package/dist/core/cache/strategies.mjs.map +1 -1
  32. package/dist/core/cart/actions.d.mts +37 -30
  33. package/dist/core/cart/actions.mjs +21 -9
  34. package/dist/core/cart/actions.mjs.map +1 -1
  35. package/dist/core/cart/attach-quantity-input.d.mts +8 -7
  36. package/dist/core/cart/attach-quantity-input.mjs +8 -7
  37. package/dist/core/cart/attach-quantity-input.mjs.map +1 -1
  38. package/dist/core/cart/buyer-identity-sync.d.mts +7 -6
  39. package/dist/core/cart/buyer-identity-sync.mjs.map +1 -1
  40. package/dist/core/cart/cart.d.mts +59 -46
  41. package/dist/core/cart/cart.mjs +46 -29
  42. package/dist/core/cart/cart.mjs.map +1 -1
  43. package/dist/core/cart/cookie.d.mts +8 -4
  44. package/dist/core/cart/cookie.mjs +8 -4
  45. package/dist/core/cart/cookie.mjs.map +1 -1
  46. package/dist/core/cart/form.d.mts +34 -20
  47. package/dist/core/cart/form.mjs +6 -4
  48. package/dist/core/cart/form.mjs.map +1 -1
  49. package/dist/core/cart/get-cart.d.mts +27 -15
  50. package/dist/core/cart/get-cart.mjs +13 -8
  51. package/dist/core/cart/get-cart.mjs.map +1 -1
  52. package/dist/core/cart/quantity.d.mts +16 -5
  53. package/dist/core/cart/quantity.mjs +16 -5
  54. package/dist/core/cart/quantity.mjs.map +1 -1
  55. package/dist/core/cart/queries.d.mts +25 -19
  56. package/dist/core/cart/queries.mjs +15 -1
  57. package/dist/core/cart/queries.mjs.map +1 -1
  58. package/dist/core/cart/server-handlers.d.mts +82 -45
  59. package/dist/core/cart/server-handlers.mjs +4 -0
  60. package/dist/core/cart/server-handlers.mjs.map +1 -1
  61. package/dist/core/cart/state.d.mts +110 -64
  62. package/dist/core/cart/state.mjs +24 -6
  63. package/dist/core/cart/state.mjs.map +1 -1
  64. package/dist/core/collection/collection.d.mts +52 -53
  65. package/dist/core/collection/collection.mjs +5 -3
  66. package/dist/core/collection/collection.mjs.map +1 -1
  67. package/dist/core/collection/reconciler.d.mts +23 -16
  68. package/dist/core/collection/reconciler.mjs +8 -4
  69. package/dist/core/collection/reconciler.mjs.map +1 -1
  70. package/dist/core/collection/state.d.mts +31 -26
  71. package/dist/core/collection/state.mjs +4 -3
  72. package/dist/core/collection/state.mjs.map +1 -1
  73. package/dist/core/collection/url.d.mts +70 -29
  74. package/dist/core/collection/url.mjs +63 -25
  75. package/dist/core/collection/url.mjs.map +1 -1
  76. package/dist/core/constants.d.mts +1 -0
  77. package/dist/core/constants.mjs +1 -0
  78. package/dist/core/constants.mjs.map +1 -1
  79. package/dist/core/logging/logging.d.mts +14 -8
  80. package/dist/core/logging/logging.mjs +15 -10
  81. package/dist/core/logging/logging.mjs.map +1 -1
  82. package/dist/core/logging/types.d.mts +28 -11
  83. package/dist/core/logging/types.mjs.map +1 -1
  84. package/dist/core/money/format.d.mts +6 -4
  85. package/dist/core/money/format.mjs +19 -9
  86. package/dist/core/money/format.mjs.map +1 -1
  87. package/dist/core/money/types.d.mts +41 -25
  88. package/dist/core/predictive-search/form.d.mts +37 -7
  89. package/dist/core/predictive-search/form.mjs +21 -3
  90. package/dist/core/predictive-search/form.mjs.map +1 -1
  91. package/dist/core/predictive-search/queries.d.mts +18 -30
  92. package/dist/core/predictive-search/queries.mjs +7 -3
  93. package/dist/core/predictive-search/queries.mjs.map +1 -1
  94. package/dist/core/predictive-search/search.d.mts +25 -27
  95. package/dist/core/predictive-search/search.mjs +20 -19
  96. package/dist/core/predictive-search/search.mjs.map +1 -1
  97. package/dist/core/predictive-search/server-handlers.d.mts +25 -26
  98. package/dist/core/predictive-search/server-handlers.mjs +4 -0
  99. package/dist/core/predictive-search/server-handlers.mjs.map +1 -1
  100. package/dist/core/predictive-search/store.d.mts +65 -24
  101. package/dist/core/predictive-search/store.mjs +12 -1
  102. package/dist/core/predictive-search/store.mjs.map +1 -1
  103. package/dist/core/predictive-search/url.d.mts +36 -37
  104. package/dist/core/predictive-search/url.mjs +14 -6
  105. package/dist/core/predictive-search/url.mjs.map +1 -1
  106. package/dist/core/product/form.d.mts +63 -16
  107. package/dist/core/product/form.mjs +8 -2
  108. package/dist/core/product/form.mjs.map +1 -1
  109. package/dist/core/product/options.d.mts +8 -10
  110. package/dist/core/product/options.mjs +8 -10
  111. package/dist/core/product/options.mjs.map +1 -1
  112. package/dist/core/product/product-form.d.mts +77 -29
  113. package/dist/core/product/product-form.mjs +32 -10
  114. package/dist/core/product/product-form.mjs.map +1 -1
  115. package/dist/core/product/state.d.mts +55 -32
  116. package/dist/core/product/url.d.mts +19 -13
  117. package/dist/core/product/url.mjs +10 -10
  118. package/dist/core/product/url.mjs.map +1 -1
  119. package/dist/core/request-context.d.mts +77 -19
  120. package/dist/core/request-context.mjs +5 -1
  121. package/dist/core/request-context.mjs.map +1 -1
  122. package/dist/core/request-routing/handle-shopify-redirects.d.mts +12 -4
  123. package/dist/core/request-routing/handle-shopify-redirects.mjs +9 -2
  124. package/dist/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
  125. package/dist/core/request-routing/handle-shopify-routes.d.mts +5 -5
  126. package/dist/core/request-routing/handle-shopify-routes.mjs +7 -5
  127. package/dist/core/request-routing/handle-shopify-routes.mjs.map +1 -1
  128. package/dist/core/request-routing/interceptors/proxy.mjs +79 -43
  129. package/dist/core/request-routing/interceptors/proxy.mjs.map +1 -1
  130. package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
  131. package/dist/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
  132. package/dist/core/request-routing/interceptors/url-redirects.mjs +6 -1
  133. package/dist/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
  134. package/dist/core/request-routing/interceptors/well-known.mjs +1 -1
  135. package/dist/core/request-routing/interceptors/well-known.mjs.map +1 -1
  136. package/dist/core/request-routing/registered-routes.d.mts +12 -0
  137. package/dist/core/request-routing/registered-routes.mjs +12 -0
  138. package/dist/core/request-routing/registered-routes.mjs.map +1 -1
  139. package/dist/core/request-routing/route-types.d.mts +43 -18
  140. package/dist/core/shop-pay/shop-pay.d.mts +71 -35
  141. package/dist/core/shop-pay/shop-pay.mjs +36 -10
  142. package/dist/core/shop-pay/shop-pay.mjs.map +1 -1
  143. package/dist/core/shopify-scripts/index.d.mts +15 -5
  144. package/dist/core/shopify-scripts/index.mjs +15 -5
  145. package/dist/core/shopify-scripts/index.mjs.map +1 -1
  146. package/dist/core/shopify-scripts/initialize.d.mts +12 -4
  147. package/dist/core/shopify-scripts/initialize.mjs +12 -4
  148. package/dist/core/shopify-scripts/initialize.mjs.map +1 -1
  149. package/dist/core/shopify-scripts/types.d.mts +58 -25
  150. package/dist/core/standard-routes/build.d.mts +11 -12
  151. package/dist/core/standard-routes/build.mjs +11 -12
  152. package/dist/core/standard-routes/build.mjs.map +1 -1
  153. package/dist/core/standard-routes/types.d.mts +30 -24
  154. package/dist/core/url.mjs +2 -1
  155. package/dist/core/url.mjs.map +1 -1
  156. package/dist/customer-account/client.d.mts +36 -69
  157. package/dist/customer-account/client.mjs +7 -8
  158. package/dist/customer-account/client.mjs.map +1 -1
  159. package/dist/customer-account/errors.d.mts +45 -36
  160. package/dist/customer-account/errors.mjs +21 -36
  161. package/dist/customer-account/errors.mjs.map +1 -1
  162. package/dist/customer-account/graphql.d.mts +11 -23
  163. package/dist/customer-account/graphql.mjs +3 -9
  164. package/dist/customer-account/graphql.mjs.map +1 -1
  165. package/dist/customer-account/session.d.mts +130 -100
  166. package/dist/customer-account/session.mjs +32 -10
  167. package/dist/customer-account/session.mjs.map +1 -1
  168. package/dist/customer-account/type-resolver.d.mts +7 -8
  169. package/dist/development/client/client.d.mts +18 -15
  170. package/dist/development/client/client.mjs +8 -3
  171. package/dist/development/client/client.mjs.map +1 -1
  172. package/dist/development/client/errors.d.mts +35 -13
  173. package/dist/development/client/errors.mjs +23 -13
  174. package/dist/development/client/errors.mjs.map +1 -1
  175. package/dist/development/client/types.d.mts +140 -90
  176. package/dist/development/core/analytics/cart-tracker.d.mts +19 -10
  177. package/dist/development/core/analytics/cart-tracker.mjs +18 -10
  178. package/dist/development/core/analytics/cart-tracker.mjs.map +1 -1
  179. package/dist/development/core/analytics/events.d.mts +17 -11
  180. package/dist/development/core/analytics/events.mjs +13 -4
  181. package/dist/development/core/analytics/events.mjs.map +1 -1
  182. package/dist/development/core/analytics/types.d.mts +207 -118
  183. package/dist/development/core/analytics/utils/flatten-connection.d.mts +11 -9
  184. package/dist/development/core/analytics/utils/flatten-connection.mjs +7 -6
  185. package/dist/development/core/analytics/utils/flatten-connection.mjs.map +1 -1
  186. package/dist/development/core/cache/fetch-with-cache.d.mts +24 -4
  187. package/dist/development/core/cache/fetch-with-cache.mjs +17 -2
  188. package/dist/development/core/cache/fetch-with-cache.mjs.map +1 -1
  189. package/dist/development/core/cache/key.d.mts +2 -0
  190. package/dist/development/core/cache/key.mjs.map +1 -1
  191. package/dist/development/core/cache/run-with-cache.d.mts +56 -8
  192. package/dist/development/core/cache/run-with-cache.mjs +17 -6
  193. package/dist/development/core/cache/run-with-cache.mjs.map +1 -1
  194. package/dist/development/core/cache/store.d.mts +8 -6
  195. package/dist/development/core/cache/store.mjs.map +1 -1
  196. package/dist/development/core/cache/strategies.d.mts +27 -2
  197. package/dist/development/core/cache/strategies.mjs +6 -0
  198. package/dist/development/core/cache/strategies.mjs.map +1 -1
  199. package/dist/development/core/cart/actions.d.mts +37 -30
  200. package/dist/development/core/cart/actions.mjs +21 -9
  201. package/dist/development/core/cart/actions.mjs.map +1 -1
  202. package/dist/development/core/cart/attach-quantity-input.d.mts +8 -7
  203. package/dist/development/core/cart/attach-quantity-input.mjs +8 -7
  204. package/dist/development/core/cart/attach-quantity-input.mjs.map +1 -1
  205. package/dist/development/core/cart/buyer-identity-sync.d.mts +6 -5
  206. package/dist/development/core/cart/buyer-identity-sync.mjs.map +1 -1
  207. package/dist/development/core/cart/cart.d.mts +59 -46
  208. package/dist/development/core/cart/cart.mjs +46 -29
  209. package/dist/development/core/cart/cart.mjs.map +1 -1
  210. package/dist/development/core/cart/cookie.d.mts +8 -4
  211. package/dist/development/core/cart/cookie.mjs +8 -4
  212. package/dist/development/core/cart/cookie.mjs.map +1 -1
  213. package/dist/development/core/cart/form.d.mts +34 -20
  214. package/dist/development/core/cart/form.mjs +6 -4
  215. package/dist/development/core/cart/form.mjs.map +1 -1
  216. package/dist/development/core/cart/get-cart.d.mts +27 -15
  217. package/dist/development/core/cart/get-cart.mjs +13 -8
  218. package/dist/development/core/cart/get-cart.mjs.map +1 -1
  219. package/dist/development/core/cart/quantity.d.mts +16 -5
  220. package/dist/development/core/cart/quantity.mjs +16 -5
  221. package/dist/development/core/cart/quantity.mjs.map +1 -1
  222. package/dist/development/core/cart/queries.d.mts +25 -19
  223. package/dist/development/core/cart/queries.mjs +15 -1
  224. package/dist/development/core/cart/queries.mjs.map +1 -1
  225. package/dist/development/core/cart/server-handlers.d.mts +82 -45
  226. package/dist/development/core/cart/server-handlers.mjs +4 -0
  227. package/dist/development/core/cart/server-handlers.mjs.map +1 -1
  228. package/dist/development/core/cart/state.d.mts +110 -64
  229. package/dist/development/core/cart/state.mjs +24 -6
  230. package/dist/development/core/cart/state.mjs.map +1 -1
  231. package/dist/development/core/collection/collection.d.mts +52 -53
  232. package/dist/development/core/collection/collection.mjs +5 -3
  233. package/dist/development/core/collection/collection.mjs.map +1 -1
  234. package/dist/development/core/collection/reconciler.d.mts +23 -16
  235. package/dist/development/core/collection/reconciler.mjs +8 -4
  236. package/dist/development/core/collection/reconciler.mjs.map +1 -1
  237. package/dist/development/core/collection/state.d.mts +31 -26
  238. package/dist/development/core/collection/state.mjs +4 -3
  239. package/dist/development/core/collection/state.mjs.map +1 -1
  240. package/dist/development/core/collection/url.d.mts +70 -29
  241. package/dist/development/core/collection/url.mjs +63 -25
  242. package/dist/development/core/collection/url.mjs.map +1 -1
  243. package/dist/development/core/constants.mjs.map +1 -1
  244. package/dist/development/core/logging/logging.d.mts +14 -8
  245. package/dist/development/core/logging/logging.mjs +15 -10
  246. package/dist/development/core/logging/logging.mjs.map +1 -1
  247. package/dist/development/core/logging/types.d.mts +28 -11
  248. package/dist/development/core/logging/types.mjs.map +1 -1
  249. package/dist/development/core/money/format.d.mts +6 -4
  250. package/dist/development/core/money/format.mjs +19 -9
  251. package/dist/development/core/money/format.mjs.map +1 -1
  252. package/dist/development/core/money/types.d.mts +41 -25
  253. package/dist/development/core/predictive-search/form.d.mts +37 -7
  254. package/dist/development/core/predictive-search/form.mjs +21 -3
  255. package/dist/development/core/predictive-search/form.mjs.map +1 -1
  256. package/dist/development/core/predictive-search/queries.d.mts +18 -30
  257. package/dist/development/core/predictive-search/queries.mjs +7 -3
  258. package/dist/development/core/predictive-search/queries.mjs.map +1 -1
  259. package/dist/development/core/predictive-search/search.d.mts +25 -27
  260. package/dist/development/core/predictive-search/search.mjs +20 -19
  261. package/dist/development/core/predictive-search/search.mjs.map +1 -1
  262. package/dist/development/core/predictive-search/server-handlers.d.mts +25 -26
  263. package/dist/development/core/predictive-search/server-handlers.mjs +4 -0
  264. package/dist/development/core/predictive-search/server-handlers.mjs.map +1 -1
  265. package/dist/development/core/predictive-search/store.d.mts +65 -24
  266. package/dist/development/core/predictive-search/store.mjs +12 -1
  267. package/dist/development/core/predictive-search/store.mjs.map +1 -1
  268. package/dist/development/core/predictive-search/url.d.mts +36 -37
  269. package/dist/development/core/predictive-search/url.mjs +14 -6
  270. package/dist/development/core/predictive-search/url.mjs.map +1 -1
  271. package/dist/development/core/product/form.d.mts +63 -16
  272. package/dist/development/core/product/form.mjs +8 -2
  273. package/dist/development/core/product/form.mjs.map +1 -1
  274. package/dist/development/core/product/options.d.mts +8 -10
  275. package/dist/development/core/product/options.mjs +8 -10
  276. package/dist/development/core/product/options.mjs.map +1 -1
  277. package/dist/development/core/product/product-form.d.mts +77 -29
  278. package/dist/development/core/product/product-form.mjs +32 -10
  279. package/dist/development/core/product/product-form.mjs.map +1 -1
  280. package/dist/development/core/product/state.d.mts +55 -32
  281. package/dist/development/core/product/url.d.mts +19 -13
  282. package/dist/development/core/product/url.mjs +10 -10
  283. package/dist/development/core/product/url.mjs.map +1 -1
  284. package/dist/development/core/request-context.d.mts +77 -19
  285. package/dist/development/core/request-context.mjs +5 -1
  286. package/dist/development/core/request-context.mjs.map +1 -1
  287. package/dist/development/core/request-routing/handle-shopify-redirects.d.mts +12 -4
  288. package/dist/development/core/request-routing/handle-shopify-redirects.mjs +9 -2
  289. package/dist/development/core/request-routing/handle-shopify-redirects.mjs.map +1 -1
  290. package/dist/development/core/request-routing/handle-shopify-routes.development.d.mts +9 -1
  291. package/dist/development/core/request-routing/handle-shopify-routes.development.mjs +7 -0
  292. package/dist/development/core/request-routing/handle-shopify-routes.development.mjs.map +1 -1
  293. package/dist/development/core/request-routing/handle-shopify-routes.mjs +7 -5
  294. package/dist/development/core/request-routing/handle-shopify-routes.mjs.map +1 -1
  295. package/dist/development/core/request-routing/interceptors/proxy.mjs +79 -43
  296. package/dist/development/core/request-routing/interceptors/proxy.mjs.map +1 -1
  297. package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs +69 -0
  298. package/dist/development/core/request-routing/interceptors/ucp-profile-proxy.mjs.map +1 -0
  299. package/dist/development/core/request-routing/interceptors/url-redirects.mjs +6 -1
  300. package/dist/development/core/request-routing/interceptors/url-redirects.mjs.map +1 -1
  301. package/dist/development/core/request-routing/interceptors/well-known.mjs +1 -1
  302. package/dist/development/core/request-routing/interceptors/well-known.mjs.map +1 -1
  303. package/dist/development/core/request-routing/registered-routes.d.mts +12 -0
  304. package/dist/development/core/request-routing/registered-routes.mjs +12 -0
  305. package/dist/development/core/request-routing/registered-routes.mjs.map +1 -1
  306. package/dist/development/core/request-routing/route-types.d.mts +43 -18
  307. package/dist/development/core/shop-pay/shop-pay.d.mts +71 -35
  308. package/dist/development/core/shop-pay/shop-pay.mjs +36 -10
  309. package/dist/development/core/shop-pay/shop-pay.mjs.map +1 -1
  310. package/dist/development/core/shopify-scripts/index.d.mts +15 -5
  311. package/dist/development/core/shopify-scripts/index.mjs +15 -5
  312. package/dist/development/core/shopify-scripts/index.mjs.map +1 -1
  313. package/dist/development/core/shopify-scripts/initialize.d.mts +12 -4
  314. package/dist/development/core/shopify-scripts/initialize.mjs +12 -4
  315. package/dist/development/core/shopify-scripts/initialize.mjs.map +1 -1
  316. package/dist/development/core/shopify-scripts/types.d.mts +58 -25
  317. package/dist/development/core/standard-routes/build.d.mts +11 -12
  318. package/dist/development/core/standard-routes/build.mjs +11 -12
  319. package/dist/development/core/standard-routes/build.mjs.map +1 -1
  320. package/dist/development/core/standard-routes/types.d.mts +30 -24
  321. package/dist/development/core/url.mjs +2 -1
  322. package/dist/development/core/url.mjs.map +1 -1
  323. package/dist/development/customer-account/session.d.mts +45 -54
  324. package/dist/development/customer-account/session.mjs +20 -4
  325. package/dist/development/customer-account/session.mjs.map +1 -1
  326. package/dist/development/globals.d.mts +20 -11
  327. package/dist/development/graphql/generated/storefront-api-types.d.mts +127 -1
  328. package/dist/development/graphql/graphql.d.mts +17 -16
  329. package/dist/development/graphql/graphql.mjs +7 -8
  330. package/dist/development/graphql/graphql.mjs.map +1 -1
  331. package/dist/development/graphql/type-resolver.d.mts +15 -8
  332. package/dist/development/react/cart.d.mts +78 -32
  333. package/dist/development/react/cart.mjs +56 -29
  334. package/dist/development/react/cart.mjs.map +1 -1
  335. package/dist/development/react/collection.d.mts +40 -22
  336. package/dist/development/react/collection.mjs +27 -7
  337. package/dist/development/react/collection.mjs.map +1 -1
  338. package/dist/development/react/predictive-search.d.mts +65 -50
  339. package/dist/development/react/predictive-search.mjs +23 -21
  340. package/dist/development/react/predictive-search.mjs.map +1 -1
  341. package/dist/development/react/product.d.mts +45 -16
  342. package/dist/development/react/product.mjs +13 -11
  343. package/dist/development/react/product.mjs.map +1 -1
  344. package/dist/development/react/shop-pay.d.mts +15 -0
  345. package/dist/development/react/shop-pay.mjs +9 -0
  346. package/dist/development/react/shop-pay.mjs.map +1 -1
  347. package/dist/development/react/shopify-scripts.d.mts +23 -2
  348. package/dist/development/react/shopify-scripts.mjs +9 -0
  349. package/dist/development/react/shopify-scripts.mjs.map +1 -1
  350. package/dist/development/vue/cart.d.mts +28 -23
  351. package/dist/development/vue/cart.mjs +42 -25
  352. package/dist/development/vue/cart.mjs.map +1 -1
  353. package/dist/development/vue/collection.d.mts +20 -12
  354. package/dist/development/vue/collection.mjs +15 -7
  355. package/dist/development/vue/collection.mjs.map +1 -1
  356. package/dist/development/vue/index.d.mts +2 -2
  357. package/dist/development/vue/index.mjs +2 -2
  358. package/dist/development/vue/predictive-search.d.mts +31 -36
  359. package/dist/development/vue/predictive-search.mjs +16 -22
  360. package/dist/development/vue/predictive-search.mjs.map +1 -1
  361. package/dist/development/vue/product.d.mts +16 -15
  362. package/dist/development/vue/product.mjs +11 -11
  363. package/dist/development/vue/product.mjs.map +1 -1
  364. package/dist/development/vue/shop-pay.d.mts +14 -17
  365. package/dist/development/vue/shop-pay.mjs +8 -0
  366. package/dist/development/vue/shop-pay.mjs.map +1 -1
  367. package/dist/development/vue/shopify-scripts.d.mts +11 -0
  368. package/dist/development/vue/shopify-scripts.mjs +6 -0
  369. package/dist/development/vue/shopify-scripts.mjs.map +1 -1
  370. package/dist/globals.d.mts +20 -11
  371. package/dist/graphql/generated/storefront-api-types.d.mts +127 -1
  372. package/dist/graphql/graphql.d.mts +17 -16
  373. package/dist/graphql/graphql.mjs +7 -8
  374. package/dist/graphql/graphql.mjs.map +1 -1
  375. package/dist/graphql/type-resolver.d.mts +15 -8
  376. package/dist/react/cart.d.mts +78 -32
  377. package/dist/react/cart.mjs +56 -29
  378. package/dist/react/cart.mjs.map +1 -1
  379. package/dist/react/collection.d.mts +40 -22
  380. package/dist/react/collection.mjs +27 -7
  381. package/dist/react/collection.mjs.map +1 -1
  382. package/dist/react/predictive-search.d.mts +65 -50
  383. package/dist/react/predictive-search.mjs +23 -21
  384. package/dist/react/predictive-search.mjs.map +1 -1
  385. package/dist/react/product.d.mts +45 -16
  386. package/dist/react/product.mjs +13 -11
  387. package/dist/react/product.mjs.map +1 -1
  388. package/dist/react/shop-pay.d.mts +15 -0
  389. package/dist/react/shop-pay.mjs +9 -0
  390. package/dist/react/shop-pay.mjs.map +1 -1
  391. package/dist/react/shopify-scripts.d.mts +23 -2
  392. package/dist/react/shopify-scripts.mjs +9 -0
  393. package/dist/react/shopify-scripts.mjs.map +1 -1
  394. package/dist/ts-plugin/index.cjs +6 -0
  395. package/dist/ts-plugin/index.cjs.map +1 -1
  396. package/dist/ts-plugin/index.d.cts +6 -0
  397. package/dist/vite/local-https.d.mts +51 -17
  398. package/dist/vite/local-https.mjs +26 -5
  399. package/dist/vite/local-https.mjs.map +1 -1
  400. package/dist/vue/cart.d.mts +28 -23
  401. package/dist/vue/cart.mjs +42 -25
  402. package/dist/vue/cart.mjs.map +1 -1
  403. package/dist/vue/collection.d.mts +20 -12
  404. package/dist/vue/collection.mjs +15 -7
  405. package/dist/vue/collection.mjs.map +1 -1
  406. package/dist/vue/index.d.mts +2 -2
  407. package/dist/vue/index.mjs +2 -2
  408. package/dist/vue/predictive-search.d.mts +31 -36
  409. package/dist/vue/predictive-search.mjs +16 -22
  410. package/dist/vue/predictive-search.mjs.map +1 -1
  411. package/dist/vue/product.d.mts +16 -15
  412. package/dist/vue/product.mjs +11 -11
  413. package/dist/vue/product.mjs.map +1 -1
  414. package/dist/vue/shop-pay.d.mts +14 -17
  415. package/dist/vue/shop-pay.mjs +8 -0
  416. package/dist/vue/shop-pay.mjs.map +1 -1
  417. package/dist/vue/shopify-scripts.d.mts +11 -0
  418. package/dist/vue/shopify-scripts.mjs +6 -0
  419. package/dist/vue/shopify-scripts.mjs.map +1 -1
  420. package/package.json +3 -1
  421. package/skills/hydrogen-analytics/SKILL.md +1 -1
  422. package/skills/hydrogen-cart-ui/SKILL.md +28 -2
  423. package/skills/hydrogen-collection-browser/SKILL.md +9 -1
  424. package/skills/hydrogen-collection-browser/references/nextjs.md +1 -1
  425. package/skills/hydrogen-collection-browser/references/nuxt.md +1 -1
  426. package/skills/hydrogen-collection-browser/references/react.md +151 -32
  427. package/skills/hydrogen-customer-account/SKILL.md +2 -0
  428. package/skills/hydrogen-request-handlers/SKILL.md +21 -11
  429. package/skills/hydrogen-setup/references/analytics.md +14 -8
  430. package/skills/hydrogen-setup/steps/1-inspect-app.md +2 -2
  431. package/skills/hydrogen-setup/steps/6-product-detail-page.md +21 -11
  432. package/skills/hydrogen-storefront-client/SKILL.md +1 -1
  433. package/skills/hydrogen-storefront-client/references/caching.md +2 -0
  434. package/skills/hydrogen-variant-form/SKILL.md +25 -7
  435. package/skills/hydrogen-variant-form/references/nextjs.md +39 -4
  436. package/skills/hydrogen-variant-form/references/nuxt.md +83 -42
  437. package/skills/hydrogen-variant-form/references/react.md +45 -9
@@ -1,55 +1,67 @@
1
1
  //#region src/core/shop-pay/shop-pay.d.ts
2
+ /**
3
+ * Tag name of the Shop Pay button custom element, `hydrogen-shop-pay-button`.
4
+ *
5
+ * Use the tag directly on a framework without a Hydrogen binding.
6
+ *
7
+ * @publicDocs
8
+ */
2
9
  declare const SHOP_PAY_BUTTON_TAG_NAME = "hydrogen-shop-pay-button";
10
+ /** Checkout target, attribution, and display settings shared by every Shop Pay button. */
3
11
  type ShopPayButtonBaseOptions = {
4
12
  /**
5
- * Absolute checkout base URL. Omit it to emit same-origin `/checkout` and
6
- * `/cart` permalink paths, which `handleShopifyRoutes` redirects to the
7
- * store's real checkout.
13
+ * Absolute checkout base URL. Omit the URL to link to the same-origin `/checkout` and
14
+ * `/cart` permalink paths, which Hydrogen's Shopify route handler redirects to the
15
+ * store's checkout.
16
+ *
17
+ * Pass the cart's checkout URL when your app doesn't send same-origin checkout paths through the Shopify route handler. The button URL keeps the query params of the checkout URL, replaces any params that Shop Pay sets, and drops the hash. A bare domain such as `my-store.myshopify.com` gets an HTTPS scheme. The Shop Pay functions throw an error when the value isn't a valid URL.
8
18
  */
9
19
  checkoutUrl?: string;
10
20
  /**
11
- * Checkout payment mode. Defaults to `"shop_pay"`. Use
12
- * `"shop_pay_installments"` only when the checkout path should open Shop Pay
13
- * Installments.
21
+ * Checkout payment mode. Defaults to `shop_pay`. Use
22
+ * `shop_pay_installments` to open Shop Pay Installments at checkout.
14
23
  */
15
24
  paymentOption?: "shop_pay" | "shop_pay_installments";
16
25
  /**
17
- * Attribution source appended to the checkout URL as `source`. Defaults to
18
- * `"hydrogen"`. Most storefronts should not override this.
26
+ * Attribution source that the checkout URL carries as `source`.
27
+ * Defaults to `hydrogen`. Most storefronts shouldn't change the source.
19
28
  */
20
29
  source?: string;
21
30
  /**
22
- * Optional attribution token appended to the checkout URL as `source_token`.
23
- * Only pass a value when Shopify has provided one for the integration.
31
+ * Attribution token that the checkout URL carries as `source_token`.
24
32
  */
25
33
  sourceToken?: string;
26
34
  /**
27
- * Content Security Policy nonce applied to the shadow root's inline style.
35
+ * Content Security Policy nonce for the button's style element.
36
+ *
37
+ * The nonce covers only the style element. Custom width and border radius values render as an inline style attribute, which a strict Content Security Policy must allow.
28
38
  */
29
39
  nonce?: string;
30
40
  /**
31
- * Sales channel that issued the Storefront API token. Omit it unless checkout
32
- * needs explicit `"headless"` or `"hydrogen"` attribution.
41
+ * Sales channel that the checkout URL carries as `channel`. Omit the channel unless
42
+ * checkout needs explicit `headless` or `hydrogen` attribution.
33
43
  */
34
44
  channel?: "headless" | "hydrogen";
35
45
  /**
36
- * Disables the button. Disabled buttons render without an `href` and include
46
+ * Disables the button. A disabled button renders without an `href` and with
37
47
  * `aria-disabled="true"`.
38
48
  */
39
49
  disabled?: boolean;
40
50
  /**
41
- * CSS width for the rendered anchor, for example `"100%"`. Omit it to use
42
- * the Shop Pay default width.
51
+ * CSS width of the button, such as `100%`. Defaults to `260px`.
52
+ *
53
+ * Pass a single CSS value. The Shop Pay functions throw an error when the width contains a semicolon or a curly brace.
43
54
  */
44
55
  width?: string;
45
56
  /**
46
- * CSS border radius for the rendered anchor, for example `"8px"`. Omit it to
47
- * use the Shop Pay default radius.
57
+ * CSS border radius of the button, such as `8px`. Defaults to `12px`.
58
+ *
59
+ * Pass a single CSS value. The Shop Pay functions throw an error when the radius contains a semicolon or a curly brace.
48
60
  */
49
61
  borderRadius?: string;
50
62
  /**
51
- * Localized accessible label for the Shop Pay logo. Defaults to `"Buy with Shop Pay"`.
52
- * Never translate the brand name `"Shop Pay"`; keep it in Latin script in every locale.
63
+ * Localized accessible label for the button. Defaults to `"Buy with Shop Pay"`.
64
+ * Keep the brand name Shop Pay untranslated and in Latin script in every locale.
53
65
  *
54
66
  * @example English
55
67
  * `"Buy with Shop Pay"`
@@ -65,37 +77,61 @@ type ShopPayButtonBaseOptions = {
65
77
  */
66
78
  accessibilityLabel?: string;
67
79
  };
80
+ /** A variant ID and an optional quantity for a Shop Pay checkout. */
68
81
  type ShopPayVariantWithQuantity = {
69
- /** ProductVariant GID or bare numeric ProductVariant ID. Product IDs are invalid. */id: string; /** Quantity for this variant. Defaults to `1`. */
82
+ /** Product variant GID or numeric variant ID. Product IDs throw an error. */id: string; /** Quantity of the variant. Defaults to `1`. */
70
83
  quantity?: number;
71
84
  };
85
+ /** Variants for a Shop Pay checkout, as all ID strings or all objects with an ID and a quantity. */
72
86
  type ShopPayVariants = readonly string[] | readonly ShopPayVariantWithQuantity[];
73
- type ShopPayButtonOptions = ShopPayButtonBaseOptions & {
87
+ /** Checkout target, variants, attribution, and display settings for a Shop Pay button. */
88
+ interface ShopPayButtonOptions extends ShopPayButtonBaseOptions {
74
89
  /**
75
- * Variants to check out immediately via a Shopify cart permalink. Omit this
76
- * for cart checkout mode, where `/checkout` checks out the current cart.
90
+ * Variants that the customer buys right away through a Shopify cart permalink. Omit the variants
91
+ * to check out the current cart.
92
+ *
93
+ * Pass either all variant ID strings or all objects with an `id` and an optional `quantity`. Each quantity must be a positive integer. The Shop Pay functions throw an error for product IDs, non-numeric variant IDs, invalid quantities, and mixed formats.
77
94
  */
78
95
  variants?: ShopPayVariants;
79
- };
96
+ }
80
97
  /**
81
- * Builds the checkout URL the Shop Pay button navigates to, or `null` when the
82
- * button is disabled. Variant mode produces a cart permalink; otherwise the
83
- * current cart checks out.
98
+ * Returns the checkout URL for a Shop Pay button. Use the URL to build your own Shop Pay link.
99
+ *
100
+ * With variants, the URL is a cart permalink that checks out those variants. Without variants, the URL checks out the current cart.
101
+ *
102
+ * @param options The variants, checkout URL, payment mode, attribution, and disabled state for the checkout URL.
103
+ * @returns The checkout URL, or `null` when `disabled` is `true`.
104
+ * @publicDocs
84
105
  */
85
106
  declare function getShopPayButtonUrl(options: ShopPayButtonOptions): string | null;
86
107
  /**
87
- * Renders the Shop Pay button as an HTML string: a self-contained wrapper
88
- * element carrying the styles and anchor it needs to work without client
89
- * JavaScript. Use it from server templates or frameworks without a Hydrogen
90
- * binding.
108
+ * Returns the Shop Pay button as an HTML string for server templates and frameworks without a Hydrogen binding.
109
+ *
110
+ * On the server, the markup includes the button's styles and link, and the button works without client JavaScript. In the browser, the function returns an empty element that renders the button when you add the element to the page.
111
+ *
112
+ * @param options The variants, checkout URL, and display settings for the button.
113
+ * @returns The Shop Pay button markup.
114
+ * @publicDocs
91
115
  */
92
116
  declare function renderShopPayButton(options: ShopPayButtonOptions): string;
93
117
  /**
94
- * Creates the Shop Pay button as a detached DOM element. The returned element
95
- * carries the button styles with it.
118
+ * Creates a Shop Pay button element in the browser. Append the element to the page.
119
+ *
120
+ * The function requires a DOM. Use `renderShopPayButton` during server rendering.
121
+ *
122
+ * @param options The variants, checkout URL, and display settings for the button.
123
+ * @returns The Shop Pay button element, ready to append to the page.
124
+ * @publicDocs
96
125
  */
97
126
  declare function createShopPayButton(options: ShopPayButtonOptions): HTMLElement;
98
- /** Registers the Shop Pay custom element. No-ops during SSR or when already registered. */
127
+ /**
128
+ * Registers the Shop Pay button custom element in the browser. Call the function when you use the `hydrogen-shop-pay-button` tag directly on a framework without a Hydrogen binding.
129
+ *
130
+ * The Hydrogen Shop Pay components, `createShopPayButton`, and `renderShopPayButton` register the element for you. The function does nothing during server rendering or when the browser already has the element.
131
+ *
132
+ * @returns Nothing.
133
+ * @publicDocs
134
+ */
99
135
  declare function defineShopPayButton(): void;
100
136
  //#endregion
101
137
  export { SHOP_PAY_BUTTON_TAG_NAME, ShopPayButtonOptions, createShopPayButton, defineShopPayButton, getShopPayButtonUrl, renderShopPayButton };
@@ -6,6 +6,13 @@ const DEFAULT_SOURCE = "hydrogen";
6
6
  const DEFAULT_ACCESSIBILITY_LABEL = "Buy with Shop Pay";
7
7
  const ERROR_PREFIX = "[hydrogen:error:ShopPay]";
8
8
  const CAN_USE_DOM = typeof document !== "undefined";
9
+ /**
10
+ * Tag name of the Shop Pay button custom element, `hydrogen-shop-pay-button`.
11
+ *
12
+ * Use the tag directly on a framework without a Hydrogen binding.
13
+ *
14
+ * @publicDocs
15
+ */
9
16
  const SHOP_PAY_BUTTON_TAG_NAME = "hydrogen-shop-pay-button";
10
17
  const SHOP_PAY_BUTTON_CLASS_NAME = "shop-pay-button";
11
18
  const SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES = [
@@ -25,9 +32,13 @@ const SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES = [
25
32
  const SHOP_PAY_BUTTON_STYLES = `:host{display:block}.${SHOP_PAY_BUTTON_CLASS_NAME}{position:relative;display:flex;align-items:center;box-sizing:border-box;margin:0;padding:10px 16px;overflow:visible;width:260px;border:none;border-radius:12px;background-color:#5433eb;color:#fff;cursor:pointer;text-decoration:none;transition:all .15s cubic-bezier(.4,0,.2,1)}.${SHOP_PAY_BUTTON_CLASS_NAME}:hover{background-color:#4524db}.${SHOP_PAY_BUTTON_CLASS_NAME}:focus-visible{outline:none;box-shadow:0 0 0 3px #9c83f8}.${SHOP_PAY_BUTTON_CLASS_NAME}[aria-disabled=true]{opacity:.5;pointer-events:none;cursor:default}.${SHOP_PAY_BUTTON_CLASS_NAME}__logo{position:relative;display:inline-block;margin:0 auto;width:88px;height:auto}`;
26
33
  const SHOP_PAY_LOGO_SVG = `<svg class="${SHOP_PAY_BUTTON_CLASS_NAME}__logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99 25" aria-hidden="true" focusable="false"><path fill="currentColor" d="M70.842 7.915h2.25c1.561 0 2.328.642 2.328 1.715 0 1.074-.739 1.715-2.259 1.715h-2.32v-3.43ZM80.525 16.142c-.879 0-1.227-.474-1.227-.948 0-.642.725-.935 2.147-1.102l1.115-.125c-.07 1.227-.892 2.175-2.035 2.175Z"/><path fill="currentColor" fill-rule="evenodd" d="M65.645.5a3.64 3.64 0 0 0-3.64 3.64V20.7a3.64 3.64 0 0 0 3.64 3.64h29.668a3.64 3.64 0 0 0 3.64-3.64V4.14A3.64 3.64 0 0 0 95.314.5H65.645Zm5.197 16.674v-4.197h2.64c2.412 0 3.695-1.353 3.695-3.402 0-2.05-1.283-3.277-3.695-3.277h-4.341v10.876h1.7Zm9.334.223c1.297 0 2.147-.572 2.538-1.548.112 1.088.767 1.645 2.189 1.269l.014-1.157c-.572.055-.683-.154-.683-.753v-2.845c0-1.673-1.102-2.663-3.138-2.663-2.008 0-3.165 1.004-3.165 2.705h1.562c0-.809.572-1.297 1.576-1.297 1.06 0 1.547.46 1.534 1.255v.363l-1.8.195c-2.021.223-3.137.99-3.137 2.329 0 1.101.781 2.147 2.51 2.147Zm9.906.32c-.711 1.73-1.855 2.245-3.64 2.245h-.766V18.54h.822c.977 0 1.45-.307 1.966-1.185L85.3 9.923h1.757l2.259 5.424 2.008-5.424h1.715l-2.956 7.795Z" clip-rule="evenodd"/><path fill="currentColor" d="M6.992 11.055c-2.359-.509-3.41-.708-3.41-1.612 0-.85.711-1.274 2.134-1.274 1.25 0 2.165.544 2.839 1.61.05.081.155.11.241.066l2.655-1.335a.186.186 0 0 0 .076-.259c-1.102-1.9-3.137-2.94-5.818-2.94C2.188 5.311 0 7.037 0 9.781c0 2.915 2.664 3.651 5.027 4.16 2.362.51 3.417.709 3.417 1.613s-.769 1.33-2.303 1.33c-1.416 0-2.467-.644-3.102-1.896a.186.186 0 0 0-.251-.082L.14 16.21a.188.188 0 0 0-.083.253c1.051 2.102 3.207 3.285 6.087 3.285 3.668 0 5.885-1.698 5.885-4.527 0-2.83-2.677-3.651-5.037-4.16v-.007ZM21.218 5.311c-1.505 0-2.835.531-3.791 1.477-.06.057-.159.015-.159-.067V.687A.185.185 0 0 0 17.081.5h-3.322a.185.185 0 0 0-.187.187v18.73c0 .104.083.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-1.587 1.223-2.804 2.87-2.804 1.649 0 2.843 1.191 2.843 2.804v8.216c0 .104.082.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-3.452-2.274-5.89-5.459-5.89ZM33.415 4.774c-1.803 0-3.493.55-4.706 1.343a.186.186 0 0 0-.06.25l1.464 2.488c.054.089.168.12.257.066a5.853 5.853 0 0 1 3.052-.834c2.899 0 5.03 2.036 5.03 4.726 0 2.292-1.706 3.99-3.868 3.99-1.762 0-2.985-1.022-2.985-2.463 0-.825.352-1.502 1.27-1.98a.183.183 0 0 0 .073-.258l-1.381-2.327a.187.187 0 0 0-.226-.079c-1.85.683-3.15 2.327-3.15 4.533 0 3.338 2.67 5.83 6.396 5.83 4.35 0 7.478-3 7.478-7.303 0-4.612-3.64-7.982-8.644-7.982ZM51.776 5.283c-1.68 0-3.182.62-4.277 1.707a.093.093 0 0 1-.16-.066v-1.31a.185.185 0 0 0-.187-.186h-3.235a.185.185 0 0 0-.188.187v18.702c0 .104.083.186.188.186h3.32a.185.185 0 0 0 .188-.186v-6.133c0-.082.099-.123.16-.07 1.091 1.012 2.536 1.603 4.19 1.603 3.897 0 6.936-3.139 6.936-7.217 0-4.078-3.042-7.217-6.935-7.217Zm-.63 11.266c-2.215 0-3.895-1.754-3.895-4.074S48.928 8.4 51.147 8.4c2.22 0 3.893 1.726 3.893 4.075 0 2.348-1.651 4.074-3.896 4.074h.003Z"/></svg>`;
27
34
  /**
28
- * Builds the checkout URL the Shop Pay button navigates to, or `null` when the
29
- * button is disabled. Variant mode produces a cart permalink; otherwise the
30
- * current cart checks out.
35
+ * Returns the checkout URL for a Shop Pay button. Use the URL to build your own Shop Pay link.
36
+ *
37
+ * With variants, the URL is a cart permalink that checks out those variants. Without variants, the URL checks out the current cart.
38
+ *
39
+ * @param options The variants, checkout URL, payment mode, attribution, and disabled state for the checkout URL.
40
+ * @returns The checkout URL, or `null` when `disabled` is `true`.
41
+ * @publicDocs
31
42
  */
32
43
  function getShopPayButtonUrl(options) {
33
44
  if (options.disabled) return null;
@@ -41,10 +52,13 @@ function getShopPayButtonUrl(options) {
41
52
  return url.toString();
42
53
  }
43
54
  /**
44
- * Renders the Shop Pay button as an HTML string: a self-contained wrapper
45
- * element carrying the styles and anchor it needs to work without client
46
- * JavaScript. Use it from server templates or frameworks without a Hydrogen
47
- * binding.
55
+ * Returns the Shop Pay button as an HTML string for server templates and frameworks without a Hydrogen binding.
56
+ *
57
+ * On the server, the markup includes the button's styles and link, and the button works without client JavaScript. In the browser, the function returns an empty element that renders the button when you add the element to the page.
58
+ *
59
+ * @param options The variants, checkout URL, and display settings for the button.
60
+ * @returns The Shop Pay button markup.
61
+ * @publicDocs
48
62
  */
49
63
  function renderShopPayButton(options) {
50
64
  defineShopPayButton();
@@ -53,8 +67,13 @@ function renderShopPayButton(options) {
53
67
  return `<${SHOP_PAY_BUTTON_TAG_NAME}${attributes ? ` ${attributes}` : ""}>${content}</${SHOP_PAY_BUTTON_TAG_NAME}>`;
54
68
  }
55
69
  /**
56
- * Creates the Shop Pay button as a detached DOM element. The returned element
57
- * carries the button styles with it.
70
+ * Creates a Shop Pay button element in the browser. Append the element to the page.
71
+ *
72
+ * The function requires a DOM. Use `renderShopPayButton` during server rendering.
73
+ *
74
+ * @param options The variants, checkout URL, and display settings for the button.
75
+ * @returns The Shop Pay button element, ready to append to the page.
76
+ * @publicDocs
58
77
  */
59
78
  function createShopPayButton(options) {
60
79
  defineShopPayButton();
@@ -72,7 +91,14 @@ function initializeShopPayButtonElement(element, options) {
72
91
  }
73
92
  renderShopPayButtonShadowRoot(shadowRoot, options);
74
93
  }
75
- /** Registers the Shop Pay custom element. No-ops during SSR or when already registered. */
94
+ /**
95
+ * Registers the Shop Pay button custom element in the browser. Call the function when you use the `hydrogen-shop-pay-button` tag directly on a framework without a Hydrogen binding.
96
+ *
97
+ * The Hydrogen Shop Pay components, `createShopPayButton`, and `renderShopPayButton` register the element for you. The function does nothing during server rendering or when the browser already has the element.
98
+ *
99
+ * @returns Nothing.
100
+ * @publicDocs
101
+ */
76
102
  function defineShopPayButton() {
77
103
  if (typeof customElements === "undefined" || typeof HTMLElement === "undefined" || customElements.get("hydrogen-shop-pay-button")) return;
78
104
  customElements.define(SHOP_PAY_BUTTON_TAG_NAME, class extends HTMLElement {
@@ -1 +1 @@
1
- {"version":3,"file":"shop-pay.mjs","names":["#connected"],"sources":["../../../src/core/shop-pay/shop-pay.ts"],"sourcesContent":["import { normalizeStoreDomain } from \"../url\";\nimport { parseGid } from \"../utils/parse-gid\";\n\nconst DEFAULT_SOURCE = \"hydrogen\";\nconst DEFAULT_ACCESSIBILITY_LABEL = \"Buy with Shop Pay\";\nconst ERROR_PREFIX = \"[hydrogen:error:ShopPay]\";\nconst CAN_USE_DOM = typeof document !== \"undefined\";\nexport const SHOP_PAY_BUTTON_TAG_NAME = \"hydrogen-shop-pay-button\";\nexport const SHOP_PAY_BUTTON_CLASS_NAME = \"shop-pay-button\";\nconst SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES = [\n \"accessibility-label\",\n \"border-radius\",\n \"channel\",\n \"checkout-url\",\n \"disabled\",\n \"nonce\",\n \"payment-option\",\n \"source\",\n \"source-token\",\n \"variants\",\n \"width\",\n] as const;\n\n/** Button styles matching the hosted shop-js pay button. */\nexport const SHOP_PAY_BUTTON_STYLES =\n `:host{display:block}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}{position:relative;display:flex;align-items:center;box-sizing:border-box;margin:0;padding:10px 16px;overflow:visible;width:260px;border:none;border-radius:12px;background-color:#5433eb;color:#fff;cursor:pointer;text-decoration:none;transition:all .15s cubic-bezier(.4,0,.2,1)}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}:hover{background-color:#4524db}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}:focus-visible{outline:none;box-shadow:0 0 0 3px #9c83f8}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}[aria-disabled=true]{opacity:.5;pointer-events:none;cursor:default}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}__logo{position:relative;display:inline-block;margin:0 auto;width:88px;height:auto}`;\n\nconst SHOP_PAY_LOGO_SVG =\n `<svg class=\"${SHOP_PAY_BUTTON_CLASS_NAME}__logo\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 99 25\" aria-hidden=\"true\" focusable=\"false\">` +\n '<path fill=\"currentColor\" d=\"M70.842 7.915h2.25c1.561 0 2.328.642 2.328 1.715 0 1.074-.739 1.715-2.259 1.715h-2.32v-3.43ZM80.525 16.142c-.879 0-1.227-.474-1.227-.948 0-.642.725-.935 2.147-1.102l1.115-.125c-.07 1.227-.892 2.175-2.035 2.175Z\"/>' +\n '<path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M65.645.5a3.64 3.64 0 0 0-3.64 3.64V20.7a3.64 3.64 0 0 0 3.64 3.64h29.668a3.64 3.64 0 0 0 3.64-3.64V4.14A3.64 3.64 0 0 0 95.314.5H65.645Zm5.197 16.674v-4.197h2.64c2.412 0 3.695-1.353 3.695-3.402 0-2.05-1.283-3.277-3.695-3.277h-4.341v10.876h1.7Zm9.334.223c1.297 0 2.147-.572 2.538-1.548.112 1.088.767 1.645 2.189 1.269l.014-1.157c-.572.055-.683-.154-.683-.753v-2.845c0-1.673-1.102-2.663-3.138-2.663-2.008 0-3.165 1.004-3.165 2.705h1.562c0-.809.572-1.297 1.576-1.297 1.06 0 1.547.46 1.534 1.255v.363l-1.8.195c-2.021.223-3.137.99-3.137 2.329 0 1.101.781 2.147 2.51 2.147Zm9.906.32c-.711 1.73-1.855 2.245-3.64 2.245h-.766V18.54h.822c.977 0 1.45-.307 1.966-1.185L85.3 9.923h1.757l2.259 5.424 2.008-5.424h1.715l-2.956 7.795Z\" clip-rule=\"evenodd\"/>' +\n '<path fill=\"currentColor\" d=\"M6.992 11.055c-2.359-.509-3.41-.708-3.41-1.612 0-.85.711-1.274 2.134-1.274 1.25 0 2.165.544 2.839 1.61.05.081.155.11.241.066l2.655-1.335a.186.186 0 0 0 .076-.259c-1.102-1.9-3.137-2.94-5.818-2.94C2.188 5.311 0 7.037 0 9.781c0 2.915 2.664 3.651 5.027 4.16 2.362.51 3.417.709 3.417 1.613s-.769 1.33-2.303 1.33c-1.416 0-2.467-.644-3.102-1.896a.186.186 0 0 0-.251-.082L.14 16.21a.188.188 0 0 0-.083.253c1.051 2.102 3.207 3.285 6.087 3.285 3.668 0 5.885-1.698 5.885-4.527 0-2.83-2.677-3.651-5.037-4.16v-.007ZM21.218 5.311c-1.505 0-2.835.531-3.791 1.477-.06.057-.159.015-.159-.067V.687A.185.185 0 0 0 17.081.5h-3.322a.185.185 0 0 0-.187.187v18.73c0 .104.083.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-1.587 1.223-2.804 2.87-2.804 1.649 0 2.843 1.191 2.843 2.804v8.216c0 .104.082.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-3.452-2.274-5.89-5.459-5.89ZM33.415 4.774c-1.803 0-3.493.55-4.706 1.343a.186.186 0 0 0-.06.25l1.464 2.488c.054.089.168.12.257.066a5.853 5.853 0 0 1 3.052-.834c2.899 0 5.03 2.036 5.03 4.726 0 2.292-1.706 3.99-3.868 3.99-1.762 0-2.985-1.022-2.985-2.463 0-.825.352-1.502 1.27-1.98a.183.183 0 0 0 .073-.258l-1.381-2.327a.187.187 0 0 0-.226-.079c-1.85.683-3.15 2.327-3.15 4.533 0 3.338 2.67 5.83 6.396 5.83 4.35 0 7.478-3 7.478-7.303 0-4.612-3.64-7.982-8.644-7.982ZM51.776 5.283c-1.68 0-3.182.62-4.277 1.707a.093.093 0 0 1-.16-.066v-1.31a.185.185 0 0 0-.187-.186h-3.235a.185.185 0 0 0-.188.187v18.702c0 .104.083.186.188.186h3.32a.185.185 0 0 0 .188-.186v-6.133c0-.082.099-.123.16-.07 1.091 1.012 2.536 1.603 4.19 1.603 3.897 0 6.936-3.139 6.936-7.217 0-4.078-3.042-7.217-6.935-7.217Zm-.63 11.266c-2.215 0-3.895-1.754-3.895-4.074S48.928 8.4 51.147 8.4c2.22 0 3.893 1.726 3.893 4.075 0 2.348-1.651 4.074-3.896 4.074h.003Z\"/>' +\n \"</svg>\";\n\ntype ShopPayButtonBaseOptions = {\n /**\n * Absolute checkout base URL. Omit it to emit same-origin `/checkout` and\n * `/cart` permalink paths, which `handleShopifyRoutes` redirects to the\n * store's real checkout.\n */\n checkoutUrl?: string;\n /**\n * Checkout payment mode. Defaults to `\"shop_pay\"`. Use\n * `\"shop_pay_installments\"` only when the checkout path should open Shop Pay\n * Installments.\n */\n paymentOption?: \"shop_pay\" | \"shop_pay_installments\";\n /**\n * Attribution source appended to the checkout URL as `source`. Defaults to\n * `\"hydrogen\"`. Most storefronts should not override this.\n */\n source?: string;\n /**\n * Optional attribution token appended to the checkout URL as `source_token`.\n * Only pass a value when Shopify has provided one for the integration.\n */\n sourceToken?: string;\n /**\n * Content Security Policy nonce applied to the shadow root's inline style.\n */\n nonce?: string;\n /**\n * Sales channel that issued the Storefront API token. Omit it unless checkout\n * needs explicit `\"headless\"` or `\"hydrogen\"` attribution.\n */\n channel?: \"headless\" | \"hydrogen\";\n /**\n * Disables the button. Disabled buttons render without an `href` and include\n * `aria-disabled=\"true\"`.\n */\n disabled?: boolean;\n /**\n * CSS width for the rendered anchor, for example `\"100%\"`. Omit it to use\n * the Shop Pay default width.\n */\n width?: string;\n /**\n * CSS border radius for the rendered anchor, for example `\"8px\"`. Omit it to\n * use the Shop Pay default radius.\n */\n borderRadius?: string;\n /**\n * Localized accessible label for the Shop Pay logo. Defaults to `\"Buy with Shop Pay\"`.\n * Never translate the brand name `\"Shop Pay\"`; keep it in Latin script in every locale.\n *\n * @example English\n * `\"Buy with Shop Pay\"`\n *\n * @example Japanese\n * `\"Shop Payで購入\"`\n *\n * @example Hindi\n * `\"Shop Pay से खरीदें\"`\n *\n * @example Arabic\n * `\"الشراء باستخدام Shop Pay\"`\n */\n accessibilityLabel?: string;\n};\n\ntype ShopPayVariantWithQuantity = {\n /** ProductVariant GID or bare numeric ProductVariant ID. Product IDs are invalid. */\n id: string;\n /** Quantity for this variant. Defaults to `1`. */\n quantity?: number;\n};\n\ntype ShopPayVariant = string | ShopPayVariantWithQuantity;\ntype ShopPayVariants = readonly string[] | readonly ShopPayVariantWithQuantity[];\n\nexport type ShopPayButtonOptions = ShopPayButtonBaseOptions & {\n /**\n * Variants to check out immediately via a Shopify cart permalink. Omit this\n * for cart checkout mode, where `/checkout` checks out the current cart.\n */\n variants?: ShopPayVariants;\n};\n\n/**\n * Builds the checkout URL the Shop Pay button navigates to, or `null` when the\n * button is disabled. Variant mode produces a cart permalink; otherwise the\n * current cart checks out.\n */\nexport function getShopPayButtonUrl(options: ShopPayButtonOptions): string | null {\n if (options.disabled) return null;\n\n const variants = getShopPayVariants(options);\n\n if (!options.checkoutUrl) {\n const search = getShopPaySearchParams(options);\n return `${variants ? `/cart/${variants}` : \"/checkout\"}?${search}`;\n }\n\n const url = variants\n ? getShopPayVariantModeUrl(options.checkoutUrl, variants)\n : getShopPayCheckoutModeUrl(options.checkoutUrl);\n\n for (const [name, value] of getShopPaySearchParams(options)) {\n url.searchParams.set(name, value);\n }\n\n return url.toString();\n}\n\n/**\n * Renders the Shop Pay button as an HTML string: a self-contained wrapper\n * element carrying the styles and anchor it needs to work without client\n * JavaScript. Use it from server templates or frameworks without a Hydrogen\n * binding.\n */\nexport function renderShopPayButton(options: ShopPayButtonOptions): string {\n defineShopPayButton();\n const attributes = serializeAttributes(getShopPayButtonElementAttributes(options));\n const content = CAN_USE_DOM ? \"\" : getShopPayButtonDeclarativeShadowDomHtml(options);\n return `<${SHOP_PAY_BUTTON_TAG_NAME}${attributes ? ` ${attributes}` : \"\"}>${content}</${SHOP_PAY_BUTTON_TAG_NAME}>`;\n}\n\n/**\n * Creates the Shop Pay button as a detached DOM element. The returned element\n * carries the button styles with it.\n */\nexport function createShopPayButton(options: ShopPayButtonOptions): HTMLElement {\n defineShopPayButton();\n const element = document.createElement(SHOP_PAY_BUTTON_TAG_NAME);\n initializeShopPayButtonElement(element, options);\n\n return element;\n}\n\nexport function initializeShopPayButtonElement(\n element: HTMLElement,\n options: ShopPayButtonOptions,\n): void {\n syncShopPayButtonElementAttributes(element, getShopPayButtonElementAttributes(options));\n\n const shadowRoot = element.shadowRoot ?? element.attachShadow({ mode: \"open\" });\n const template = element.querySelector(\"template[shadowrootmode]\");\n\n if (template instanceof HTMLTemplateElement) {\n shadowRoot.append(template.content.cloneNode(true));\n template.remove();\n }\n\n renderShopPayButtonShadowRoot(shadowRoot, options);\n}\n\n/** Registers the Shop Pay custom element. No-ops during SSR or when already registered. */\nexport function defineShopPayButton(): void {\n if (\n typeof customElements === \"undefined\" ||\n typeof HTMLElement === \"undefined\" ||\n customElements.get(SHOP_PAY_BUTTON_TAG_NAME)\n ) {\n return;\n }\n\n customElements.define(\n SHOP_PAY_BUTTON_TAG_NAME,\n class extends HTMLElement {\n #connected = false;\n\n static observedAttributes = SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES;\n\n connectedCallback(): void {\n this.#connected = true;\n initializeShopPayButtonElement(this, getShopPayButtonOptions(this));\n }\n\n attributeChangedCallback(): void {\n if (!this.#connected || !this.shadowRoot) return;\n renderShopPayButtonShadowRoot(this.shadowRoot, getShopPayButtonOptions(this));\n }\n },\n );\n}\n\n/** Anchor attributes shared by server and browser shadow-root rendering. */\nexport function getShopPayButtonAnchorAttributes(\n options: ShopPayButtonOptions,\n): Record<string, string> {\n const attributes: Record<string, string> = {\n class: SHOP_PAY_BUTTON_CLASS_NAME,\n target: \"_self\",\n };\n\n const href = getShopPayButtonUrl(options);\n if (href) {\n attributes.href = href;\n } else {\n attributes.role = \"link\";\n attributes[\"aria-disabled\"] = \"true\";\n }\n\n const style = serializeStyleProperties(getShopPayButtonStyleProperties(options));\n if (style) attributes.style = style;\n\n attributes[\"aria-label\"] = getShopPayAccessibilityLabel(options.accessibilityLabel);\n\n return attributes;\n}\n\nexport function getShopPayButtonElementContentHtml(options: ShopPayButtonOptions): string {\n return `<style${getShopPayButtonStyleNonceAttribute(options)}>${SHOP_PAY_BUTTON_STYLES}</style><a ${serializeAttributes(getShopPayButtonAnchorAttributes(options))}>${getShopPayButtonContentHtml()}</a>`;\n}\n\nexport function getShopPayButtonDeclarativeShadowDomHtml(options: ShopPayButtonOptions): string {\n return `<template shadowrootmode=\"open\" shadowroot=\"open\">${getShopPayButtonElementContentHtml(options)}</template>`;\n}\n\nexport function getShopPayButtonElementAttributes(\n options: ShopPayButtonOptions,\n): Record<string, string> {\n const attributes: Record<string, string> = {};\n const variants = getShopPayVariants(options);\n\n if (hasContent(options.accessibilityLabel)) {\n attributes[\"accessibility-label\"] = options.accessibilityLabel.trim();\n }\n if (hasContent(options.borderRadius)) {\n attributes[\"border-radius\"] = normalizeCssValue(\"borderRadius\", options.borderRadius);\n }\n if (options.channel) attributes.channel = options.channel;\n if (options.checkoutUrl !== undefined) attributes[\"checkout-url\"] = options.checkoutUrl;\n if (options.disabled) attributes.disabled = \"\";\n if (hasContent(options.nonce)) attributes.nonce = options.nonce.trim();\n if (options.paymentOption) attributes[\"payment-option\"] = options.paymentOption;\n if (options.source !== undefined) attributes.source = options.source;\n if (options.sourceToken !== undefined) attributes[\"source-token\"] = options.sourceToken;\n if (variants) attributes.variants = variants;\n if (hasContent(options.width)) {\n attributes.width = normalizeCssValue(\"width\", options.width);\n }\n\n return attributes;\n}\n\n/** Inner HTML for the shadow root's anchor. */\nexport function getShopPayButtonContentHtml(): string {\n return SHOP_PAY_LOGO_SVG;\n}\n\nfunction getShopPayButtonStyleProperties(\n options: Pick<ShopPayButtonOptions, \"width\" | \"borderRadius\">,\n): Record<string, string> {\n const style: Record<string, string> = {};\n\n if (hasContent(options.width)) style.width = normalizeCssValue(\"width\", options.width);\n if (hasContent(options.borderRadius)) {\n style.borderRadius = normalizeCssValue(\"borderRadius\", options.borderRadius);\n }\n\n return style;\n}\n\nfunction getShopPaySearchParams(options: ShopPayButtonOptions): URLSearchParams {\n const params = new URLSearchParams();\n params.set(\"payment\", options.paymentOption ?? \"shop_pay\");\n\n const source = options.source ?? DEFAULT_SOURCE;\n if (source) params.set(\"source\", source);\n if (options.sourceToken) params.set(\"source_token\", options.sourceToken);\n if (options.channel) params.set(\"channel\", options.channel);\n\n return params;\n}\n\nfunction getShopPayCheckoutModeUrl(checkoutUrl: string): URL {\n const url = parseCheckoutUrl(checkoutUrl);\n if (url.pathname === \"/\") url.pathname = \"/checkout\";\n url.hash = \"\";\n return url;\n}\n\nfunction getShopPayVariantModeUrl(checkoutUrl: string, variants: string): URL {\n const url = parseCheckoutUrl(checkoutUrl);\n url.pathname = `/cart/${variants}`;\n url.hash = \"\";\n return url;\n}\n\nfunction parseCheckoutUrl(checkoutUrl: string): URL {\n try {\n return new URL(normalizeStoreDomain(checkoutUrl.trim()));\n } catch {\n throw shopPayError('Shop Pay requires a valid \"checkoutUrl\" value.');\n }\n}\n\nfunction getShopPayVariants(options: ShopPayButtonOptions): string | undefined {\n const variantsInput: readonly ShopPayVariant[] | undefined = options.variants;\n\n if (!Array.isArray(variantsInput) || variantsInput.length === 0) return undefined;\n\n if (variantsInput.every(isVariantId)) {\n return variantsInput.map((id) => `${normalizeVariantId(id)}:1`).join(\",\");\n }\n\n if (variantsInput.every(isVariantWithQuantity)) {\n return variantsInput\n .map(({ id, quantity }) => {\n return `${normalizeVariantId(id)}:${normalizeQuantity(quantity)}`;\n })\n .join(\",\");\n }\n\n throw shopPayError(\n \"Shop Pay variants must be either variant IDs or objects with an id and quantity.\",\n );\n}\n\nfunction isVariantId(variant: ShopPayVariant): variant is string {\n return typeof variant === \"string\";\n}\n\nfunction getShopPayButtonOptions(element: HTMLElement): ShopPayButtonOptions {\n return {\n accessibilityLabel: element.getAttribute(\"accessibility-label\") ?? undefined,\n borderRadius: element.getAttribute(\"border-radius\") ?? undefined,\n channel: parseChannel(element.getAttribute(\"channel\")),\n checkoutUrl: element.getAttribute(\"checkout-url\") ?? undefined,\n disabled: element.hasAttribute(\"disabled\"),\n nonce: element.nonce || element.getAttribute(\"nonce\") || undefined,\n paymentOption: parsePaymentOption(element.getAttribute(\"payment-option\")),\n source: element.getAttribute(\"source\") ?? undefined,\n sourceToken: element.getAttribute(\"source-token\") ?? undefined,\n variants: parseVariantsAttribute(element.getAttribute(\"variants\")),\n width: element.getAttribute(\"width\") ?? undefined,\n };\n}\n\nfunction parseVariantsAttribute(value: string | null): ShopPayVariants | undefined {\n if (!value) return undefined;\n\n return value.split(\",\").map((entry) => {\n const [id = \"\", quantity] = entry.split(\":\");\n return { id, quantity: quantity === undefined ? undefined : Number(quantity) };\n });\n}\n\nfunction parsePaymentOption(value: string | null): ShopPayButtonOptions[\"paymentOption\"] {\n return value === \"shop_pay\" || value === \"shop_pay_installments\" ? value : undefined;\n}\n\nfunction parseChannel(value: string | null): ShopPayButtonOptions[\"channel\"] {\n return value === \"headless\" || value === \"hydrogen\" ? value : undefined;\n}\n\nfunction renderShopPayButtonShadowRoot(\n shadowRoot: ShadowRoot,\n options: ShopPayButtonOptions,\n): void {\n let style = shadowRoot.querySelector(\"style\");\n if (!(style instanceof HTMLStyleElement)) {\n style = shadowRoot.ownerDocument.createElement(\"style\");\n shadowRoot.prepend(style);\n }\n\n const nextNonce = hasContent(options.nonce) ? options.nonce.trim() : undefined;\n const nonceChanged = (style.nonce || undefined) !== nextNonce;\n if (nextNonce) {\n style.nonce = nextNonce;\n } else {\n style.removeAttribute(\"nonce\");\n }\n if (nonceChanged) style.textContent = \"\";\n if (style.textContent !== SHOP_PAY_BUTTON_STYLES) style.textContent = SHOP_PAY_BUTTON_STYLES;\n\n let anchor = shadowRoot.querySelector(\"a\");\n if (!(anchor instanceof HTMLAnchorElement)) {\n anchor = shadowRoot.ownerDocument.createElement(\"a\");\n shadowRoot.append(anchor);\n }\n\n syncAttributes(anchor, getShopPayButtonAnchorAttributes(options));\n const content = getShopPayButtonContentHtml();\n if (anchor.innerHTML !== content) anchor.innerHTML = content;\n}\n\nfunction syncAttributes(element: Element, attributes: Record<string, string>): void {\n for (const name of element.getAttributeNames()) {\n if (!(name in attributes)) element.removeAttribute(name);\n }\n\n for (const [name, value] of Object.entries(attributes)) {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n }\n}\n\nfunction syncShopPayButtonElementAttributes(\n element: Element,\n attributes: Record<string, string>,\n): void {\n for (const name of SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES) {\n if (!(name in attributes)) element.removeAttribute(name);\n }\n\n for (const [name, value] of Object.entries(attributes)) {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n }\n}\n\nfunction isVariantWithQuantity(\n variant: ShopPayVariant | undefined,\n): variant is ShopPayVariantWithQuantity {\n return typeof variant === \"object\" && variant !== null && typeof variant.id === \"string\";\n}\n\nfunction normalizeVariantId(id: string): string {\n const parsed = parseGid(id);\n const bareId = parsed.id || id.trim();\n\n if (parsed.resource && parsed.resource !== \"ProductVariant\") {\n throw shopPayError(\n \"Shop Pay variant IDs must be Shopify ProductVariant GIDs or bare numeric variant IDs.\",\n );\n }\n\n if (/^\\d+$/.test(bareId)) return bareId;\n\n throw shopPayError(\n \"Shop Pay variant IDs must be Shopify ProductVariant GIDs or bare numeric variant IDs.\",\n );\n}\n\nfunction normalizeQuantity(quantity = 1): number {\n if (!Number.isInteger(quantity) || quantity < 1) {\n throw shopPayError(\"Shop Pay variant quantities must be positive integers.\");\n }\n\n return quantity;\n}\n\nfunction escapeText(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttribute(value: string): string {\n return escapeText(value).replace(/\"/g, \"&quot;\");\n}\n\nfunction getShopPayAccessibilityLabel(label: string | undefined): string {\n return hasContent(label) ? label.trim() : DEFAULT_ACCESSIBILITY_LABEL;\n}\n\nfunction getShopPayButtonStyleNonceAttribute(options: Pick<ShopPayButtonOptions, \"nonce\">): string {\n return hasContent(options.nonce) ? ` nonce=\"${escapeAttribute(options.nonce.trim())}\"` : \"\";\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction normalizeCssValue(name: \"width\" | \"borderRadius\", value: string): string {\n const normalized = value.trim();\n if (/[;{}]/.test(normalized)) {\n throw shopPayError(`Shop Pay ${name} must be a single CSS value.`);\n }\n return normalized;\n}\n\nfunction serializeAttributes(attributes: Record<string, string>): string {\n return Object.entries(attributes)\n .map(([name, value]) => `${name}=\"${escapeAttribute(value)}\"`)\n .join(\" \");\n}\n\nfunction serializeStyleProperties(style: Record<string, string>): string {\n return Object.entries(style)\n .map(([name, value]) => `${hyphenateStyleName(name)}:${value}`)\n .join(\";\");\n}\n\nfunction hyphenateStyleName(name: string): string {\n return name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\n\nfunction shopPayError(message: string): Error {\n return new Error(`${ERROR_PREFIX} ${message}`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"shop-pay.mjs","names":["#connected"],"sources":["../../../src/core/shop-pay/shop-pay.ts"],"sourcesContent":["import { normalizeStoreDomain } from \"../url\";\nimport { parseGid } from \"../utils/parse-gid\";\n\nconst DEFAULT_SOURCE = \"hydrogen\";\nconst DEFAULT_ACCESSIBILITY_LABEL = \"Buy with Shop Pay\";\nconst ERROR_PREFIX = \"[hydrogen:error:ShopPay]\";\nconst CAN_USE_DOM = typeof document !== \"undefined\";\n/**\n * Tag name of the Shop Pay button custom element, `hydrogen-shop-pay-button`.\n *\n * Use the tag directly on a framework without a Hydrogen binding.\n *\n * @publicDocs\n */\nexport const SHOP_PAY_BUTTON_TAG_NAME = \"hydrogen-shop-pay-button\";\nexport const SHOP_PAY_BUTTON_CLASS_NAME = \"shop-pay-button\";\nconst SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES = [\n \"accessibility-label\",\n \"border-radius\",\n \"channel\",\n \"checkout-url\",\n \"disabled\",\n \"nonce\",\n \"payment-option\",\n \"source\",\n \"source-token\",\n \"variants\",\n \"width\",\n] as const;\n\n/** Button styles matching the hosted shop-js pay button. */\nexport const SHOP_PAY_BUTTON_STYLES =\n `:host{display:block}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}{position:relative;display:flex;align-items:center;box-sizing:border-box;margin:0;padding:10px 16px;overflow:visible;width:260px;border:none;border-radius:12px;background-color:#5433eb;color:#fff;cursor:pointer;text-decoration:none;transition:all .15s cubic-bezier(.4,0,.2,1)}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}:hover{background-color:#4524db}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}:focus-visible{outline:none;box-shadow:0 0 0 3px #9c83f8}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}[aria-disabled=true]{opacity:.5;pointer-events:none;cursor:default}` +\n `.${SHOP_PAY_BUTTON_CLASS_NAME}__logo{position:relative;display:inline-block;margin:0 auto;width:88px;height:auto}`;\n\nconst SHOP_PAY_LOGO_SVG =\n `<svg class=\"${SHOP_PAY_BUTTON_CLASS_NAME}__logo\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 99 25\" aria-hidden=\"true\" focusable=\"false\">` +\n '<path fill=\"currentColor\" d=\"M70.842 7.915h2.25c1.561 0 2.328.642 2.328 1.715 0 1.074-.739 1.715-2.259 1.715h-2.32v-3.43ZM80.525 16.142c-.879 0-1.227-.474-1.227-.948 0-.642.725-.935 2.147-1.102l1.115-.125c-.07 1.227-.892 2.175-2.035 2.175Z\"/>' +\n '<path fill=\"currentColor\" fill-rule=\"evenodd\" d=\"M65.645.5a3.64 3.64 0 0 0-3.64 3.64V20.7a3.64 3.64 0 0 0 3.64 3.64h29.668a3.64 3.64 0 0 0 3.64-3.64V4.14A3.64 3.64 0 0 0 95.314.5H65.645Zm5.197 16.674v-4.197h2.64c2.412 0 3.695-1.353 3.695-3.402 0-2.05-1.283-3.277-3.695-3.277h-4.341v10.876h1.7Zm9.334.223c1.297 0 2.147-.572 2.538-1.548.112 1.088.767 1.645 2.189 1.269l.014-1.157c-.572.055-.683-.154-.683-.753v-2.845c0-1.673-1.102-2.663-3.138-2.663-2.008 0-3.165 1.004-3.165 2.705h1.562c0-.809.572-1.297 1.576-1.297 1.06 0 1.547.46 1.534 1.255v.363l-1.8.195c-2.021.223-3.137.99-3.137 2.329 0 1.101.781 2.147 2.51 2.147Zm9.906.32c-.711 1.73-1.855 2.245-3.64 2.245h-.766V18.54h.822c.977 0 1.45-.307 1.966-1.185L85.3 9.923h1.757l2.259 5.424 2.008-5.424h1.715l-2.956 7.795Z\" clip-rule=\"evenodd\"/>' +\n '<path fill=\"currentColor\" d=\"M6.992 11.055c-2.359-.509-3.41-.708-3.41-1.612 0-.85.711-1.274 2.134-1.274 1.25 0 2.165.544 2.839 1.61.05.081.155.11.241.066l2.655-1.335a.186.186 0 0 0 .076-.259c-1.102-1.9-3.137-2.94-5.818-2.94C2.188 5.311 0 7.037 0 9.781c0 2.915 2.664 3.651 5.027 4.16 2.362.51 3.417.709 3.417 1.613s-.769 1.33-2.303 1.33c-1.416 0-2.467-.644-3.102-1.896a.186.186 0 0 0-.251-.082L.14 16.21a.188.188 0 0 0-.083.253c1.051 2.102 3.207 3.285 6.087 3.285 3.668 0 5.885-1.698 5.885-4.527 0-2.83-2.677-3.651-5.037-4.16v-.007ZM21.218 5.311c-1.505 0-2.835.531-3.791 1.477-.06.057-.159.015-.159-.067V.687A.185.185 0 0 0 17.081.5h-3.322a.185.185 0 0 0-.187.187v18.73c0 .104.083.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-1.587 1.223-2.804 2.87-2.804 1.649 0 2.843 1.191 2.843 2.804v8.216c0 .104.082.186.187.186h3.322a.185.185 0 0 0 .187-.186V11.2c0-3.452-2.274-5.89-5.459-5.89ZM33.415 4.774c-1.803 0-3.493.55-4.706 1.343a.186.186 0 0 0-.06.25l1.464 2.488c.054.089.168.12.257.066a5.853 5.853 0 0 1 3.052-.834c2.899 0 5.03 2.036 5.03 4.726 0 2.292-1.706 3.99-3.868 3.99-1.762 0-2.985-1.022-2.985-2.463 0-.825.352-1.502 1.27-1.98a.183.183 0 0 0 .073-.258l-1.381-2.327a.187.187 0 0 0-.226-.079c-1.85.683-3.15 2.327-3.15 4.533 0 3.338 2.67 5.83 6.396 5.83 4.35 0 7.478-3 7.478-7.303 0-4.612-3.64-7.982-8.644-7.982ZM51.776 5.283c-1.68 0-3.182.62-4.277 1.707a.093.093 0 0 1-.16-.066v-1.31a.185.185 0 0 0-.187-.186h-3.235a.185.185 0 0 0-.188.187v18.702c0 .104.083.186.188.186h3.32a.185.185 0 0 0 .188-.186v-6.133c0-.082.099-.123.16-.07 1.091 1.012 2.536 1.603 4.19 1.603 3.897 0 6.936-3.139 6.936-7.217 0-4.078-3.042-7.217-6.935-7.217Zm-.63 11.266c-2.215 0-3.895-1.754-3.895-4.074S48.928 8.4 51.147 8.4c2.22 0 3.893 1.726 3.893 4.075 0 2.348-1.651 4.074-3.896 4.074h.003Z\"/>' +\n \"</svg>\";\n\n/** Checkout target, attribution, and display settings shared by every Shop Pay button. */\ntype ShopPayButtonBaseOptions = {\n /**\n * Absolute checkout base URL. Omit the URL to link to the same-origin `/checkout` and\n * `/cart` permalink paths, which Hydrogen's Shopify route handler redirects to the\n * store's checkout.\n *\n * Pass the cart's checkout URL when your app doesn't send same-origin checkout paths through the Shopify route handler. The button URL keeps the query params of the checkout URL, replaces any params that Shop Pay sets, and drops the hash. A bare domain such as `my-store.myshopify.com` gets an HTTPS scheme. The Shop Pay functions throw an error when the value isn't a valid URL.\n */\n checkoutUrl?: string;\n /**\n * Checkout payment mode. Defaults to `shop_pay`. Use\n * `shop_pay_installments` to open Shop Pay Installments at checkout.\n */\n paymentOption?: \"shop_pay\" | \"shop_pay_installments\";\n /**\n * Attribution source that the checkout URL carries as `source`.\n * Defaults to `hydrogen`. Most storefronts shouldn't change the source.\n */\n source?: string;\n /**\n * Attribution token that the checkout URL carries as `source_token`.\n */\n sourceToken?: string;\n /**\n * Content Security Policy nonce for the button's style element.\n *\n * The nonce covers only the style element. Custom width and border radius values render as an inline style attribute, which a strict Content Security Policy must allow.\n */\n nonce?: string;\n /**\n * Sales channel that the checkout URL carries as `channel`. Omit the channel unless\n * checkout needs explicit `headless` or `hydrogen` attribution.\n */\n channel?: \"headless\" | \"hydrogen\";\n /**\n * Disables the button. A disabled button renders without an `href` and with\n * `aria-disabled=\"true\"`.\n */\n disabled?: boolean;\n /**\n * CSS width of the button, such as `100%`. Defaults to `260px`.\n *\n * Pass a single CSS value. The Shop Pay functions throw an error when the width contains a semicolon or a curly brace.\n */\n width?: string;\n /**\n * CSS border radius of the button, such as `8px`. Defaults to `12px`.\n *\n * Pass a single CSS value. The Shop Pay functions throw an error when the radius contains a semicolon or a curly brace.\n */\n borderRadius?: string;\n /**\n * Localized accessible label for the button. Defaults to `\"Buy with Shop Pay\"`.\n * Keep the brand name Shop Pay untranslated and in Latin script in every locale.\n *\n * @example English\n * `\"Buy with Shop Pay\"`\n *\n * @example Japanese\n * `\"Shop Payで購入\"`\n *\n * @example Hindi\n * `\"Shop Pay से खरीदें\"`\n *\n * @example Arabic\n * `\"الشراء باستخدام Shop Pay\"`\n */\n accessibilityLabel?: string;\n};\n\n/** A variant ID and an optional quantity for a Shop Pay checkout. */\ntype ShopPayVariantWithQuantity = {\n /** Product variant GID or numeric variant ID. Product IDs throw an error. */\n id: string;\n /** Quantity of the variant. Defaults to `1`. */\n quantity?: number;\n};\n\ntype ShopPayVariant = string | ShopPayVariantWithQuantity;\n/** Variants for a Shop Pay checkout, as all ID strings or all objects with an ID and a quantity. */\ntype ShopPayVariants = readonly string[] | readonly ShopPayVariantWithQuantity[];\n\n/** Checkout target, variants, attribution, and display settings for a Shop Pay button. */\nexport interface ShopPayButtonOptions extends ShopPayButtonBaseOptions {\n /**\n * Variants that the customer buys right away through a Shopify cart permalink. Omit the variants\n * to check out the current cart.\n *\n * Pass either all variant ID strings or all objects with an `id` and an optional `quantity`. Each quantity must be a positive integer. The Shop Pay functions throw an error for product IDs, non-numeric variant IDs, invalid quantities, and mixed formats.\n */\n variants?: ShopPayVariants;\n}\n\n/**\n * Returns the checkout URL for a Shop Pay button. Use the URL to build your own Shop Pay link.\n *\n * With variants, the URL is a cart permalink that checks out those variants. Without variants, the URL checks out the current cart.\n *\n * @param options The variants, checkout URL, payment mode, attribution, and disabled state for the checkout URL.\n * @returns The checkout URL, or `null` when `disabled` is `true`.\n * @publicDocs\n */\nexport function getShopPayButtonUrl(options: ShopPayButtonOptions): string | null {\n if (options.disabled) return null;\n\n const variants = getShopPayVariants(options);\n\n if (!options.checkoutUrl) {\n const search = getShopPaySearchParams(options);\n return `${variants ? `/cart/${variants}` : \"/checkout\"}?${search}`;\n }\n\n const url = variants\n ? getShopPayVariantModeUrl(options.checkoutUrl, variants)\n : getShopPayCheckoutModeUrl(options.checkoutUrl);\n\n for (const [name, value] of getShopPaySearchParams(options)) {\n url.searchParams.set(name, value);\n }\n\n return url.toString();\n}\n\n/**\n * Returns the Shop Pay button as an HTML string for server templates and frameworks without a Hydrogen binding.\n *\n * On the server, the markup includes the button's styles and link, and the button works without client JavaScript. In the browser, the function returns an empty element that renders the button when you add the element to the page.\n *\n * @param options The variants, checkout URL, and display settings for the button.\n * @returns The Shop Pay button markup.\n * @publicDocs\n */\nexport function renderShopPayButton(options: ShopPayButtonOptions): string {\n defineShopPayButton();\n const attributes = serializeAttributes(getShopPayButtonElementAttributes(options));\n const content = CAN_USE_DOM ? \"\" : getShopPayButtonDeclarativeShadowDomHtml(options);\n return `<${SHOP_PAY_BUTTON_TAG_NAME}${attributes ? ` ${attributes}` : \"\"}>${content}</${SHOP_PAY_BUTTON_TAG_NAME}>`;\n}\n\n/**\n * Creates a Shop Pay button element in the browser. Append the element to the page.\n *\n * The function requires a DOM. Use `renderShopPayButton` during server rendering.\n *\n * @param options The variants, checkout URL, and display settings for the button.\n * @returns The Shop Pay button element, ready to append to the page.\n * @publicDocs\n */\nexport function createShopPayButton(options: ShopPayButtonOptions): HTMLElement {\n defineShopPayButton();\n const element = document.createElement(SHOP_PAY_BUTTON_TAG_NAME);\n initializeShopPayButtonElement(element, options);\n\n return element;\n}\n\nexport function initializeShopPayButtonElement(\n element: HTMLElement,\n options: ShopPayButtonOptions,\n): void {\n syncShopPayButtonElementAttributes(element, getShopPayButtonElementAttributes(options));\n\n const shadowRoot = element.shadowRoot ?? element.attachShadow({ mode: \"open\" });\n const template = element.querySelector(\"template[shadowrootmode]\");\n\n if (template instanceof HTMLTemplateElement) {\n shadowRoot.append(template.content.cloneNode(true));\n template.remove();\n }\n\n renderShopPayButtonShadowRoot(shadowRoot, options);\n}\n\n/**\n * Registers the Shop Pay button custom element in the browser. Call the function when you use the `hydrogen-shop-pay-button` tag directly on a framework without a Hydrogen binding.\n *\n * The Hydrogen Shop Pay components, `createShopPayButton`, and `renderShopPayButton` register the element for you. The function does nothing during server rendering or when the browser already has the element.\n *\n * @returns Nothing.\n * @publicDocs\n */\nexport function defineShopPayButton(): void {\n if (\n typeof customElements === \"undefined\" ||\n typeof HTMLElement === \"undefined\" ||\n customElements.get(SHOP_PAY_BUTTON_TAG_NAME)\n ) {\n return;\n }\n\n customElements.define(\n SHOP_PAY_BUTTON_TAG_NAME,\n class extends HTMLElement {\n #connected = false;\n\n static observedAttributes = SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES;\n\n connectedCallback(): void {\n this.#connected = true;\n initializeShopPayButtonElement(this, getShopPayButtonOptions(this));\n }\n\n attributeChangedCallback(): void {\n if (!this.#connected || !this.shadowRoot) return;\n renderShopPayButtonShadowRoot(this.shadowRoot, getShopPayButtonOptions(this));\n }\n },\n );\n}\n\n/** Anchor attributes shared by server and browser shadow-root rendering. */\nexport function getShopPayButtonAnchorAttributes(\n options: ShopPayButtonOptions,\n): Record<string, string> {\n const attributes: Record<string, string> = {\n class: SHOP_PAY_BUTTON_CLASS_NAME,\n target: \"_self\",\n };\n\n const href = getShopPayButtonUrl(options);\n if (href) {\n attributes.href = href;\n } else {\n attributes.role = \"link\";\n attributes[\"aria-disabled\"] = \"true\";\n }\n\n const style = serializeStyleProperties(getShopPayButtonStyleProperties(options));\n if (style) attributes.style = style;\n\n attributes[\"aria-label\"] = getShopPayAccessibilityLabel(options.accessibilityLabel);\n\n return attributes;\n}\n\nexport function getShopPayButtonElementContentHtml(options: ShopPayButtonOptions): string {\n return `<style${getShopPayButtonStyleNonceAttribute(options)}>${SHOP_PAY_BUTTON_STYLES}</style><a ${serializeAttributes(getShopPayButtonAnchorAttributes(options))}>${getShopPayButtonContentHtml()}</a>`;\n}\n\nexport function getShopPayButtonDeclarativeShadowDomHtml(options: ShopPayButtonOptions): string {\n return `<template shadowrootmode=\"open\" shadowroot=\"open\">${getShopPayButtonElementContentHtml(options)}</template>`;\n}\n\nexport function getShopPayButtonElementAttributes(\n options: ShopPayButtonOptions,\n): Record<string, string> {\n const attributes: Record<string, string> = {};\n const variants = getShopPayVariants(options);\n\n if (hasContent(options.accessibilityLabel)) {\n attributes[\"accessibility-label\"] = options.accessibilityLabel.trim();\n }\n if (hasContent(options.borderRadius)) {\n attributes[\"border-radius\"] = normalizeCssValue(\"borderRadius\", options.borderRadius);\n }\n if (options.channel) attributes.channel = options.channel;\n if (options.checkoutUrl !== undefined) attributes[\"checkout-url\"] = options.checkoutUrl;\n if (options.disabled) attributes.disabled = \"\";\n if (hasContent(options.nonce)) attributes.nonce = options.nonce.trim();\n if (options.paymentOption) attributes[\"payment-option\"] = options.paymentOption;\n if (options.source !== undefined) attributes.source = options.source;\n if (options.sourceToken !== undefined) attributes[\"source-token\"] = options.sourceToken;\n if (variants) attributes.variants = variants;\n if (hasContent(options.width)) {\n attributes.width = normalizeCssValue(\"width\", options.width);\n }\n\n return attributes;\n}\n\n/** Inner HTML for the shadow root's anchor. */\nexport function getShopPayButtonContentHtml(): string {\n return SHOP_PAY_LOGO_SVG;\n}\n\nfunction getShopPayButtonStyleProperties(\n options: Pick<ShopPayButtonOptions, \"width\" | \"borderRadius\">,\n): Record<string, string> {\n const style: Record<string, string> = {};\n\n if (hasContent(options.width)) style.width = normalizeCssValue(\"width\", options.width);\n if (hasContent(options.borderRadius)) {\n style.borderRadius = normalizeCssValue(\"borderRadius\", options.borderRadius);\n }\n\n return style;\n}\n\nfunction getShopPaySearchParams(options: ShopPayButtonOptions): URLSearchParams {\n const params = new URLSearchParams();\n params.set(\"payment\", options.paymentOption ?? \"shop_pay\");\n\n const source = options.source ?? DEFAULT_SOURCE;\n if (source) params.set(\"source\", source);\n if (options.sourceToken) params.set(\"source_token\", options.sourceToken);\n if (options.channel) params.set(\"channel\", options.channel);\n\n return params;\n}\n\nfunction getShopPayCheckoutModeUrl(checkoutUrl: string): URL {\n const url = parseCheckoutUrl(checkoutUrl);\n if (url.pathname === \"/\") url.pathname = \"/checkout\";\n url.hash = \"\";\n return url;\n}\n\nfunction getShopPayVariantModeUrl(checkoutUrl: string, variants: string): URL {\n const url = parseCheckoutUrl(checkoutUrl);\n url.pathname = `/cart/${variants}`;\n url.hash = \"\";\n return url;\n}\n\nfunction parseCheckoutUrl(checkoutUrl: string): URL {\n try {\n return new URL(normalizeStoreDomain(checkoutUrl.trim()));\n } catch {\n throw shopPayError('Shop Pay requires a valid \"checkoutUrl\" value.');\n }\n}\n\nfunction getShopPayVariants(options: ShopPayButtonOptions): string | undefined {\n const variantsInput: readonly ShopPayVariant[] | undefined = options.variants;\n\n if (!Array.isArray(variantsInput) || variantsInput.length === 0) return undefined;\n\n if (variantsInput.every(isVariantId)) {\n return variantsInput.map((id) => `${normalizeVariantId(id)}:1`).join(\",\");\n }\n\n if (variantsInput.every(isVariantWithQuantity)) {\n return variantsInput\n .map(({ id, quantity }) => {\n return `${normalizeVariantId(id)}:${normalizeQuantity(quantity)}`;\n })\n .join(\",\");\n }\n\n throw shopPayError(\n \"Shop Pay variants must be either variant IDs or objects with an id and quantity.\",\n );\n}\n\nfunction isVariantId(variant: ShopPayVariant): variant is string {\n return typeof variant === \"string\";\n}\n\nfunction getShopPayButtonOptions(element: HTMLElement): ShopPayButtonOptions {\n return {\n accessibilityLabel: element.getAttribute(\"accessibility-label\") ?? undefined,\n borderRadius: element.getAttribute(\"border-radius\") ?? undefined,\n channel: parseChannel(element.getAttribute(\"channel\")),\n checkoutUrl: element.getAttribute(\"checkout-url\") ?? undefined,\n disabled: element.hasAttribute(\"disabled\"),\n nonce: element.nonce || element.getAttribute(\"nonce\") || undefined,\n paymentOption: parsePaymentOption(element.getAttribute(\"payment-option\")),\n source: element.getAttribute(\"source\") ?? undefined,\n sourceToken: element.getAttribute(\"source-token\") ?? undefined,\n variants: parseVariantsAttribute(element.getAttribute(\"variants\")),\n width: element.getAttribute(\"width\") ?? undefined,\n };\n}\n\nfunction parseVariantsAttribute(value: string | null): ShopPayVariants | undefined {\n if (!value) return undefined;\n\n return value.split(\",\").map((entry) => {\n const [id = \"\", quantity] = entry.split(\":\");\n return { id, quantity: quantity === undefined ? undefined : Number(quantity) };\n });\n}\n\nfunction parsePaymentOption(value: string | null): ShopPayButtonOptions[\"paymentOption\"] {\n return value === \"shop_pay\" || value === \"shop_pay_installments\" ? value : undefined;\n}\n\nfunction parseChannel(value: string | null): ShopPayButtonOptions[\"channel\"] {\n return value === \"headless\" || value === \"hydrogen\" ? value : undefined;\n}\n\nfunction renderShopPayButtonShadowRoot(\n shadowRoot: ShadowRoot,\n options: ShopPayButtonOptions,\n): void {\n let style = shadowRoot.querySelector(\"style\");\n if (!(style instanceof HTMLStyleElement)) {\n style = shadowRoot.ownerDocument.createElement(\"style\");\n shadowRoot.prepend(style);\n }\n\n const nextNonce = hasContent(options.nonce) ? options.nonce.trim() : undefined;\n const nonceChanged = (style.nonce || undefined) !== nextNonce;\n if (nextNonce) {\n style.nonce = nextNonce;\n } else {\n style.removeAttribute(\"nonce\");\n }\n if (nonceChanged) style.textContent = \"\";\n if (style.textContent !== SHOP_PAY_BUTTON_STYLES) style.textContent = SHOP_PAY_BUTTON_STYLES;\n\n let anchor = shadowRoot.querySelector(\"a\");\n if (!(anchor instanceof HTMLAnchorElement)) {\n anchor = shadowRoot.ownerDocument.createElement(\"a\");\n shadowRoot.append(anchor);\n }\n\n syncAttributes(anchor, getShopPayButtonAnchorAttributes(options));\n const content = getShopPayButtonContentHtml();\n if (anchor.innerHTML !== content) anchor.innerHTML = content;\n}\n\nfunction syncAttributes(element: Element, attributes: Record<string, string>): void {\n for (const name of element.getAttributeNames()) {\n if (!(name in attributes)) element.removeAttribute(name);\n }\n\n for (const [name, value] of Object.entries(attributes)) {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n }\n}\n\nfunction syncShopPayButtonElementAttributes(\n element: Element,\n attributes: Record<string, string>,\n): void {\n for (const name of SHOP_PAY_BUTTON_OBSERVED_ATTRIBUTES) {\n if (!(name in attributes)) element.removeAttribute(name);\n }\n\n for (const [name, value] of Object.entries(attributes)) {\n if (element.getAttribute(name) !== value) element.setAttribute(name, value);\n }\n}\n\nfunction isVariantWithQuantity(\n variant: ShopPayVariant | undefined,\n): variant is ShopPayVariantWithQuantity {\n return typeof variant === \"object\" && variant !== null && typeof variant.id === \"string\";\n}\n\nfunction normalizeVariantId(id: string): string {\n const parsed = parseGid(id);\n const bareId = parsed.id || id.trim();\n\n if (parsed.resource && parsed.resource !== \"ProductVariant\") {\n throw shopPayError(\n \"Shop Pay variant IDs must be Shopify ProductVariant GIDs or bare numeric variant IDs.\",\n );\n }\n\n if (/^\\d+$/.test(bareId)) return bareId;\n\n throw shopPayError(\n \"Shop Pay variant IDs must be Shopify ProductVariant GIDs or bare numeric variant IDs.\",\n );\n}\n\nfunction normalizeQuantity(quantity = 1): number {\n if (!Number.isInteger(quantity) || quantity < 1) {\n throw shopPayError(\"Shop Pay variant quantities must be positive integers.\");\n }\n\n return quantity;\n}\n\nfunction escapeText(value: string): string {\n return value.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\nfunction escapeAttribute(value: string): string {\n return escapeText(value).replace(/\"/g, \"&quot;\");\n}\n\nfunction getShopPayAccessibilityLabel(label: string | undefined): string {\n return hasContent(label) ? label.trim() : DEFAULT_ACCESSIBILITY_LABEL;\n}\n\nfunction getShopPayButtonStyleNonceAttribute(options: Pick<ShopPayButtonOptions, \"nonce\">): string {\n return hasContent(options.nonce) ? ` nonce=\"${escapeAttribute(options.nonce.trim())}\"` : \"\";\n}\n\nfunction hasContent(value: string | undefined): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\nfunction normalizeCssValue(name: \"width\" | \"borderRadius\", value: string): string {\n const normalized = value.trim();\n if (/[;{}]/.test(normalized)) {\n throw shopPayError(`Shop Pay ${name} must be a single CSS value.`);\n }\n return normalized;\n}\n\nfunction serializeAttributes(attributes: Record<string, string>): string {\n return Object.entries(attributes)\n .map(([name, value]) => `${name}=\"${escapeAttribute(value)}\"`)\n .join(\" \");\n}\n\nfunction serializeStyleProperties(style: Record<string, string>): string {\n return Object.entries(style)\n .map(([name, value]) => `${hyphenateStyleName(name)}:${value}`)\n .join(\";\");\n}\n\nfunction hyphenateStyleName(name: string): string {\n return name.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\n}\n\nfunction shopPayError(message: string): Error {\n return new Error(`${ERROR_PREFIX} ${message}`);\n}\n"],"mappings":"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"}
@@ -2,11 +2,15 @@ import { ShopifyRoutesOptions, ShopifyScriptTagDescriptor, ShopifyScriptTagDescr
2
2
  import { initializeShopifyScripts } from "./initialize.mjs";
3
3
  //#region src/core/shopify-scripts/index.d.ts
4
4
  /**
5
- * Returns grouped Shopify storefront script/link descriptors for SSR frameworks and bindings.
5
+ * Returns Shopify's storefront script and link tags as descriptors.
6
6
  *
7
- * Framework bindings wrap this with `initializeShopifyScripts()` to form their `ShopifyScripts`
8
- * component. Frameworks without a binding can render these descriptors during SSR and call
9
- * `initializeShopifyScripts()` during browser hydration.
7
+ * Render the descriptors in the document head during server rendering, then call
8
+ * `initializeShopifyScripts` in the browser. Keep the tags in the returned order. The inline
9
+ * scripts set up globals that later scripts read.
10
+ *
11
+ * @param options - The shop details, the localization, the consent configuration, and the features whose scripts to load.
12
+ * @returns The link tags, the script tags, and a combined list with links first.
13
+ * @publicDocs
10
14
  */
11
15
  declare function getShopifyScriptTags({
12
16
  account,
@@ -20,7 +24,13 @@ declare function getShopifyScriptTags({
20
24
  inbox
21
25
  }: ShopifyScriptTagsOptions): ShopifyScriptTagDescriptors;
22
26
  /**
23
- * Renders all Shopify storefront script/link descriptors to HTML strings.
27
+ * Renders Shopify's storefront script and link tags to HTML strings.
28
+ *
29
+ * Use the function when your framework accepts raw HTML in the document head.
30
+ *
31
+ * @param options The shop details and the features, such as account and analytics, whose scripts to load.
32
+ * @returns One HTML string per tag, with link tags first.
33
+ * @publicDocs
24
34
  */
25
35
  declare function renderShopifyScriptTags(options: ShopifyScriptTagsOptions): string[];
26
36
  //#endregion
@@ -7,11 +7,15 @@ import { initializeShopifyScripts } from "./initialize.mjs";
7
7
 
8
8
  //#region src/core/shopify-scripts/index.ts
9
9
  /**
10
- * Returns grouped Shopify storefront script/link descriptors for SSR frameworks and bindings.
10
+ * Returns Shopify's storefront script and link tags as descriptors.
11
11
  *
12
- * Framework bindings wrap this with `initializeShopifyScripts()` to form their `ShopifyScripts`
13
- * component. Frameworks without a binding can render these descriptors during SSR and call
14
- * `initializeShopifyScripts()` during browser hydration.
12
+ * Render the descriptors in the document head during server rendering, then call
13
+ * `initializeShopifyScripts` in the browser. Keep the tags in the returned order. The inline
14
+ * scripts set up globals that later scripts read.
15
+ *
16
+ * @param options - The shop details, the localization, the consent configuration, and the features whose scripts to load.
17
+ * @returns The link tags, the script tags, and a combined list with links first.
18
+ * @publicDocs
15
19
  */
16
20
  function getShopifyScriptTags({ account = false, analytics, consent, debug, i18n, nonce, shop, shopifyAnalytics = true, inbox = false }) {
17
21
  const nonceAttributes = nonce !== void 0 ? { nonce } : void 0;
@@ -126,7 +130,13 @@ function getShopifyScriptTags({ account = false, analytics, consent, debug, i18n
126
130
  };
127
131
  }
128
132
  /**
129
- * Renders all Shopify storefront script/link descriptors to HTML strings.
133
+ * Renders Shopify's storefront script and link tags to HTML strings.
134
+ *
135
+ * Use the function when your framework accepts raw HTML in the document head.
136
+ *
137
+ * @param options The shop details and the features, such as account and analytics, whose scripts to load.
138
+ * @returns One HTML string per tag, with link tags first.
139
+ * @publicDocs
130
140
  */
131
141
  function renderShopifyScriptTags(options) {
132
142
  return getShopifyScriptTags(options).tags.map(renderShopifyScriptTag);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/core/shopify-scripts/index.ts"],"sourcesContent":["import { getShopifyAnalyticsBusScript, getShopifyAnalyticsConfig } from \"./analytics\";\nimport {\n SHOPIFY_ACCOUNT_SCRIPT,\n SHOPIFY_CONSENT_API_SCRIPT,\n SHOPIFY_CDN_ORIGIN,\n SHOPIFY_CONSENT_SCRIPT_ID,\n SHOPIFY_PRIVACY_BANNER_SCRIPT,\n SHOPIFY_SHOP_APP_ORIGIN,\n SHOPIFY_INBOX_SCRIPT,\n SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_INSPECTOR_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n} from \"./constants\";\nimport { getShopifyGlobalBootstrapScript } from \"./global\";\nimport { getPerfKitScript } from \"./perfkit\";\nimport { renderShopifyScriptTag } from \"./render\";\nimport type {\n ShopifyLinkDescriptor,\n ShopifyScriptDescriptor,\n ShopifyScriptTagDescriptors,\n ShopifyScriptTagsOptions,\n} from \"./types\";\n\nexport {\n CONSENT_TRACKING_API_LOADED_EVENT,\n SHOPIFY_ACCOUNT_SCRIPT,\n SHOPIFY_CDN_ORIGIN,\n SHOPIFY_CONSENT_API_SCRIPT,\n SHOPIFY_PERF_KIT_SCRIPT,\n SHOPIFY_PRIVACY_BANNER_SCRIPT,\n SHOPIFY_SHOP_APP_ORIGIN,\n SHOPIFY_INBOX_SCRIPT,\n SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n SHOPIFY_STOREFRONT_WEBMCP_SCRIPT,\n VISITOR_CONSENT_COLLECTED_EVENT,\n} from \"./constants\";\nexport { getShopifyGlobal, getShopifyGlobalBootstrapScript } from \"./global\";\nexport { initializeShopifyScripts } from \"./initialize\";\nexport { renderShopifyScriptTag } from \"./render\";\nexport type {\n ShopifyScriptsAnalyticsConfig,\n ShopifyRoutesOptions,\n ShopifyScriptTagDescriptor,\n ShopifyScriptTagDescriptors,\n ShopifyScriptTagsOptions,\n ShopifyScriptsOptions,\n ShopifyScriptsI18n,\n ShopifyScriptsShop,\n} from \"./types\";\n\n/**\n * Returns grouped Shopify storefront script/link descriptors for SSR frameworks and bindings.\n *\n * Framework bindings wrap this with `initializeShopifyScripts()` to form their `ShopifyScripts`\n * component. Frameworks without a binding can render these descriptors during SSR and call\n * `initializeShopifyScripts()` during browser hydration.\n */\n// oxlint-disable-next-line complexity -- ordered assembly of optional Shopify script tags; each flag adds one branch and splitting would obscure the required load order\nexport function getShopifyScriptTags({\n account = false,\n analytics,\n consent,\n debug,\n i18n,\n nonce,\n shop,\n shopifyAnalytics = true,\n inbox = false,\n}: ShopifyScriptTagsOptions): ShopifyScriptTagDescriptors {\n const nonceAttributes = nonce !== undefined ? { nonce } : undefined;\n const analyticsConfig = getShopifyAnalyticsConfig({ analytics, consent, shop });\n\n const links: ShopifyLinkDescriptor[] = [\n {\n tagName: \"link\",\n attributes: {\n rel: \"preconnect\",\n href: SHOPIFY_CDN_ORIGIN,\n },\n },\n {\n tagName: \"link\",\n attributes: {\n rel: \"preconnect\",\n href: SHOPIFY_SHOP_APP_ORIGIN,\n },\n },\n {\n tagName: \"link\",\n attributes: {\n rel: \"prefetch\",\n as: \"script\",\n href: SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n crossorigin: \"anonymous\",\n },\n },\n ];\n const scripts: ShopifyScriptDescriptor[] = [\n {\n tagName: \"script\",\n attributes: { id: \"shopify-global-bootstrap\", ...nonceAttributes },\n innerHTML: getShopifyGlobalBootstrapScript({ i18n, shop }),\n },\n {\n tagName: \"script\",\n attributes: {\n id: \"shopify-standard-actions\",\n type: \"module\",\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n },\n },\n ];\n\n if (__DEV__ && debug?.standardEventsInspector) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-standard-events-inspector\",\n defer: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_STANDARD_EVENTS_INSPECTOR_SCRIPT,\n },\n });\n }\n\n if (inbox) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-inbox\",\n type: \"module\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_INBOX_SCRIPT,\n },\n });\n }\n\n if (account) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-account\",\n type: \"module\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_ACCOUNT_SCRIPT,\n },\n });\n }\n\n // Install readiness listeners before loading the async consent library so a\n // cached script cannot finish initialization before Hydrogen starts listening.\n scripts.push({\n tagName: \"script\",\n attributes: { id: \"shopify-analytics-bus\", ...nonceAttributes },\n innerHTML: getShopifyAnalyticsBusScript(analyticsConfig),\n });\n\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: SHOPIFY_CONSENT_SCRIPT_ID,\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src:\n consent?.mode === \"default-banner\"\n ? SHOPIFY_PRIVACY_BANNER_SCRIPT\n : SHOPIFY_CONSENT_API_SCRIPT,\n },\n });\n\n if (shopifyAnalytics) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-storefront-analytics\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n },\n });\n }\n\n const perfKitScript = getPerfKitScript(shop, nonceAttributes);\n if (perfKitScript) {\n scripts.push(perfKitScript);\n }\n\n return {\n links,\n scripts,\n get tags() {\n return [...links, ...scripts];\n },\n };\n}\n\n/**\n * Renders all Shopify storefront script/link descriptors to HTML strings.\n */\nexport function renderShopifyScriptTags(options: ShopifyScriptTagsOptions): string[] {\n return getShopifyScriptTags(options).tags.map(renderShopifyScriptTag);\n}\n"],"mappings":";;;;;;;;;;;;;;;AA6DA,SAAgB,qBAAqB,EACnC,UAAU,OACV,WACA,SACA,OACA,MACA,OACA,MACA,mBAAmB,MACnB,QAAQ,SACgD;CACxD,MAAM,kBAAkB,UAAU,SAAY,EAAE,OAAO,GAAG;CAC1D,MAAM,kBAAkB,0BAA0B;EAAE;EAAW;EAAS;EAAM,CAAC;CAE/E,MAAM,QAAiC;EACrC;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,MAAM;IACP;GACF;EACD;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,MAAM;IACP;GACF;EACD;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,IAAI;IACJ,MAAM;IACN,aAAa;IACd;GACF;EACF;CACD,MAAM,UAAqC,CACzC;EACE,SAAS;EACT,YAAY;GAAE,IAAI;GAA4B,GAAG;GAAiB;EAClE,WAAW,gCAAgC;GAAE;GAAM;GAAM,CAAC;EAC3D,EACD;EACE,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CACF;AAeD,KAAI,MACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;AAGJ,KAAI,QACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;AAKJ,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GAAE,IAAI;GAAyB,GAAG;GAAiB;EAC/D,WAAW,6BAA6B,gBAAgB;EACzD,CAAC;AAEF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,OAAO;GACP,aAAa;GACb,GAAG;GACH,KACE,SAAS,SAAS,mBACd,gCACA;GACP;EACF,CAAC;AAEF,KAAI,iBACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;CAGJ,MAAM,gBAAgB,iBAAiB,MAAM,gBAAgB;AAC7D,KAAI,cACF,SAAQ,KAAK,cAAc;AAG7B,QAAO;EACL;EACA;EACA,IAAI,OAAO;AACT,UAAO,CAAC,GAAG,OAAO,GAAG,QAAQ;;EAEhC;;;;;AAMH,SAAgB,wBAAwB,SAA6C;AACnF,QAAO,qBAAqB,QAAQ,CAAC,KAAK,IAAI,uBAAuB"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/core/shopify-scripts/index.ts"],"sourcesContent":["import { getShopifyAnalyticsBusScript, getShopifyAnalyticsConfig } from \"./analytics\";\nimport {\n SHOPIFY_ACCOUNT_SCRIPT,\n SHOPIFY_CONSENT_API_SCRIPT,\n SHOPIFY_CDN_ORIGIN,\n SHOPIFY_CONSENT_SCRIPT_ID,\n SHOPIFY_PRIVACY_BANNER_SCRIPT,\n SHOPIFY_SHOP_APP_ORIGIN,\n SHOPIFY_INBOX_SCRIPT,\n SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_INSPECTOR_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n} from \"./constants\";\nimport { getShopifyGlobalBootstrapScript } from \"./global\";\nimport { getPerfKitScript } from \"./perfkit\";\nimport { renderShopifyScriptTag } from \"./render\";\nimport type {\n ShopifyLinkDescriptor,\n ShopifyScriptDescriptor,\n ShopifyScriptTagDescriptors,\n ShopifyScriptTagsOptions,\n} from \"./types\";\n\nexport {\n CONSENT_TRACKING_API_LOADED_EVENT,\n SHOPIFY_ACCOUNT_SCRIPT,\n SHOPIFY_CDN_ORIGIN,\n SHOPIFY_CONSENT_API_SCRIPT,\n SHOPIFY_PERF_KIT_SCRIPT,\n SHOPIFY_PRIVACY_BANNER_SCRIPT,\n SHOPIFY_SHOP_APP_ORIGIN,\n SHOPIFY_INBOX_SCRIPT,\n SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n SHOPIFY_STOREFRONT_WEBMCP_SCRIPT,\n VISITOR_CONSENT_COLLECTED_EVENT,\n} from \"./constants\";\nexport { getShopifyGlobal, getShopifyGlobalBootstrapScript } from \"./global\";\nexport { initializeShopifyScripts } from \"./initialize\";\nexport { renderShopifyScriptTag } from \"./render\";\nexport type {\n ShopifyScriptsAnalyticsConfig,\n ShopifyRoutesOptions,\n ShopifyScriptTagDescriptor,\n ShopifyScriptTagDescriptors,\n ShopifyScriptTagsOptions,\n ShopifyScriptsOptions,\n ShopifyScriptsI18n,\n ShopifyScriptsShop,\n} from \"./types\";\n\n/**\n * Returns Shopify's storefront script and link tags as descriptors.\n *\n * Render the descriptors in the document head during server rendering, then call\n * `initializeShopifyScripts` in the browser. Keep the tags in the returned order. The inline\n * scripts set up globals that later scripts read.\n *\n * @param options - The shop details, the localization, the consent configuration, and the features whose scripts to load.\n * @returns The link tags, the script tags, and a combined list with links first.\n * @publicDocs\n */\n// oxlint-disable-next-line complexity -- ordered assembly of optional Shopify script tags; each flag adds one branch and splitting would obscure the required load order\nexport function getShopifyScriptTags({\n account = false,\n analytics,\n consent,\n debug,\n i18n,\n nonce,\n shop,\n shopifyAnalytics = true,\n inbox = false,\n}: ShopifyScriptTagsOptions): ShopifyScriptTagDescriptors {\n const nonceAttributes = nonce !== undefined ? { nonce } : undefined;\n const analyticsConfig = getShopifyAnalyticsConfig({ analytics, consent, shop });\n\n const links: ShopifyLinkDescriptor[] = [\n {\n tagName: \"link\",\n attributes: {\n rel: \"preconnect\",\n href: SHOPIFY_CDN_ORIGIN,\n },\n },\n {\n tagName: \"link\",\n attributes: {\n rel: \"preconnect\",\n href: SHOPIFY_SHOP_APP_ORIGIN,\n },\n },\n {\n tagName: \"link\",\n attributes: {\n rel: \"prefetch\",\n as: \"script\",\n href: SHOPIFY_STOREFRONT_STANDARD_EVENTS_SCRIPT,\n crossorigin: \"anonymous\",\n },\n },\n ];\n const scripts: ShopifyScriptDescriptor[] = [\n {\n tagName: \"script\",\n attributes: { id: \"shopify-global-bootstrap\", ...nonceAttributes },\n innerHTML: getShopifyGlobalBootstrapScript({ i18n, shop }),\n },\n {\n tagName: \"script\",\n attributes: {\n id: \"shopify-standard-actions\",\n type: \"module\",\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_STANDARD_ACTIONS_SCRIPT,\n },\n },\n ];\n\n if (__DEV__ && debug?.standardEventsInspector) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-standard-events-inspector\",\n defer: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_STANDARD_EVENTS_INSPECTOR_SCRIPT,\n },\n });\n }\n\n if (inbox) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-inbox\",\n type: \"module\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_INBOX_SCRIPT,\n },\n });\n }\n\n if (account) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-account\",\n type: \"module\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_ACCOUNT_SCRIPT,\n },\n });\n }\n\n // Install readiness listeners before loading the async consent library so a\n // cached script cannot finish initialization before Hydrogen starts listening.\n scripts.push({\n tagName: \"script\",\n attributes: { id: \"shopify-analytics-bus\", ...nonceAttributes },\n innerHTML: getShopifyAnalyticsBusScript(analyticsConfig),\n });\n\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: SHOPIFY_CONSENT_SCRIPT_ID,\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src:\n consent?.mode === \"default-banner\"\n ? SHOPIFY_PRIVACY_BANNER_SCRIPT\n : SHOPIFY_CONSENT_API_SCRIPT,\n },\n });\n\n if (shopifyAnalytics) {\n scripts.push({\n tagName: \"script\",\n attributes: {\n id: \"shopify-storefront-analytics\",\n async: true,\n crossorigin: \"anonymous\",\n ...nonceAttributes,\n src: SHOPIFY_STOREFRONT_ANALYTICS_SCRIPT,\n },\n });\n }\n\n const perfKitScript = getPerfKitScript(shop, nonceAttributes);\n if (perfKitScript) {\n scripts.push(perfKitScript);\n }\n\n return {\n links,\n scripts,\n get tags() {\n return [...links, ...scripts];\n },\n };\n}\n\n/**\n * Renders Shopify's storefront script and link tags to HTML strings.\n *\n * Use the function when your framework accepts raw HTML in the document head.\n *\n * @param options The shop details and the features, such as account and analytics, whose scripts to load.\n * @returns One HTML string per tag, with link tags first.\n * @publicDocs\n */\nexport function renderShopifyScriptTags(options: ShopifyScriptTagsOptions): string[] {\n return getShopifyScriptTags(options).tags.map(renderShopifyScriptTag);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiEA,SAAgB,qBAAqB,EACnC,UAAU,OACV,WACA,SACA,OACA,MACA,OACA,MACA,mBAAmB,MACnB,QAAQ,SACgD;CACxD,MAAM,kBAAkB,UAAU,SAAY,EAAE,OAAO,GAAG;CAC1D,MAAM,kBAAkB,0BAA0B;EAAE;EAAW;EAAS;EAAM,CAAC;CAE/E,MAAM,QAAiC;EACrC;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,MAAM;IACP;GACF;EACD;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,MAAM;IACP;GACF;EACD;GACE,SAAS;GACT,YAAY;IACV,KAAK;IACL,IAAI;IACJ,MAAM;IACN,aAAa;IACd;GACF;EACF;CACD,MAAM,UAAqC,CACzC;EACE,SAAS;EACT,YAAY;GAAE,IAAI;GAA4B,GAAG;GAAiB;EAClE,WAAW,gCAAgC;GAAE;GAAM;GAAM,CAAC;EAC3D,EACD;EACE,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CACF;AAeD,KAAI,MACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;AAGJ,KAAI,QACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,MAAM;GACN,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;AAKJ,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GAAE,IAAI;GAAyB,GAAG;GAAiB;EAC/D,WAAW,6BAA6B,gBAAgB;EACzD,CAAC;AAEF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,OAAO;GACP,aAAa;GACb,GAAG;GACH,KACE,SAAS,SAAS,mBACd,gCACA;GACP;EACF,CAAC;AAEF,KAAI,iBACF,SAAQ,KAAK;EACX,SAAS;EACT,YAAY;GACV,IAAI;GACJ,OAAO;GACP,aAAa;GACb,GAAG;GACH,KAAK;GACN;EACF,CAAC;CAGJ,MAAM,gBAAgB,iBAAiB,MAAM,gBAAgB;AAC7D,KAAI,cACF,SAAQ,KAAK,cAAc;AAG7B,QAAO;EACL;EACA;EACA,IAAI,OAAO;AACT,UAAO,CAAC,GAAG,OAAO,GAAG,QAAQ;;EAEhC;;;;;;;;;;;AAYH,SAAgB,wBAAwB,SAA6C;AACnF,QAAO,qBAAqB,QAAQ,CAAC,KAAK,IAAI,uBAAuB"}
@@ -2,11 +2,19 @@ import { InitializeShopifyScriptsOptions } from "./types.mjs";
2
2
 
3
3
  //#region src/core/shopify-scripts/initialize.d.ts
4
4
  /**
5
- * Initializes Shopify browser script behavior for frameworks without a Hydrogen binding.
5
+ * Starts Shopify's scripts in the browser for frameworks without a Hydrogen binding. Call it after
6
+ * hydration, with the consent configuration that you passed to `getShopifyScriptTags`.
6
7
  *
7
- * This is the browser hydration half of `getShopifyScriptTags()`: framework bindings combine both
8
- * into a `ShopifyScripts` component, while custom integrations can render script tags during SSR
9
- * and call this helper from their browser lifecycle.
8
+ * The function sets up `window.Shopify.routes`, and sends a page view event on load and after each
9
+ * navigation that changes the path or query. In the custom banner consent mode, Hydrogen calls your
10
+ * setup callback after the Customer Privacy API loads. A custom banner configuration without a
11
+ * setup callback logs a warning, and analytics events stay blocked. When the browser supports
12
+ * WebMCP, the function also loads Shopify's WebMCP tools. Set `webMcp` to `false` to skip them.
13
+ *
14
+ * @param options - The consent configuration, the route settings, and whether to load WebMCP tools.
15
+ * @returns A promise that resolves after the WebMCP tools load or fail to load, or right away when the function skips WebMCP.
16
+ *
17
+ * @publicDocs
10
18
  */
11
19
  declare function initializeShopifyScripts({
12
20
  consent,
@@ -7,11 +7,19 @@ import { loadShopifyWebMcpTools } from "./webmcp.mjs";
7
7
  //#region src/core/shopify-scripts/initialize.ts
8
8
  const log = getLogger("consent");
9
9
  /**
10
- * Initializes Shopify browser script behavior for frameworks without a Hydrogen binding.
10
+ * Starts Shopify's scripts in the browser for frameworks without a Hydrogen binding. Call it after
11
+ * hydration, with the consent configuration that you passed to `getShopifyScriptTags`.
11
12
  *
12
- * This is the browser hydration half of `getShopifyScriptTags()`: framework bindings combine both
13
- * into a `ShopifyScripts` component, while custom integrations can render script tags during SSR
14
- * and call this helper from their browser lifecycle.
13
+ * The function sets up `window.Shopify.routes`, and sends a page view event on load and after each
14
+ * navigation that changes the path or query. In the custom banner consent mode, Hydrogen calls your
15
+ * setup callback after the Customer Privacy API loads. A custom banner configuration without a
16
+ * setup callback logs a warning, and analytics events stay blocked. When the browser supports
17
+ * WebMCP, the function also loads Shopify's WebMCP tools. Set `webMcp` to `false` to skip them.
18
+ *
19
+ * @param options - The consent configuration, the route settings, and whether to load WebMCP tools.
20
+ * @returns A promise that resolves after the WebMCP tools load or fail to load, or right away when the function skips WebMCP.
21
+ *
22
+ * @publicDocs
15
23
  */
16
24
  function initializeShopifyScripts({ consent, navigate, routes, webMcp = true }) {
17
25
  configureShopifyRouting({
@@ -1 +1 @@
1
- {"version":3,"file":"initialize.mjs","names":[],"sources":["../../../src/core/shopify-scripts/initialize.ts"],"sourcesContent":["import { initializeCustomConsent } from \"../analytics/custom-consent\";\nimport { getLogger } from \"../logging\";\nimport { configureShopifyRouting } from \"./global\";\nimport { initializeShopifyPageViewEvents } from \"./page-view\";\nimport type { InitializeShopifyScriptsOptions } from \"./types\";\nimport { loadShopifyWebMcpTools } from \"./webmcp\";\n\nconst log = getLogger(\"consent\");\n\n/**\n * Initializes Shopify browser script behavior for frameworks without a Hydrogen binding.\n *\n * This is the browser hydration half of `getShopifyScriptTags()`: framework bindings combine both\n * into a `ShopifyScripts` component, while custom integrations can render script tags during SSR\n * and call this helper from their browser lifecycle.\n */\nexport function initializeShopifyScripts({\n consent,\n navigate,\n routes,\n webMcp = true,\n}: InitializeShopifyScriptsOptions): Promise<boolean | void> {\n configureShopifyRouting({ navigate, routes });\n initializeShopifyPageViewEvents();\n\n if (consent?.mode === \"custom-banner\") {\n if (typeof consent.setup !== \"function\") {\n log.warn(\n \"custom-banner requires a consent.setup callback; analytics delivery remains blocked until setup completes\",\n );\n } else {\n try {\n initializeCustomConsent(consent.setup);\n } catch (error) {\n log.error(\"custom consent initialization failed\", { error });\n }\n }\n }\n\n if (!webMcp) return Promise.resolve();\n\n return loadShopifyWebMcpTools();\n}\n"],"mappings":";;;;;;;AAOA,MAAM,MAAM,UAAU,UAAU;;;;;;;;AAShC,SAAgB,yBAAyB,EACvC,SACA,UACA,QACA,SAAS,QACkD;AAC3D,yBAAwB;EAAE;EAAU;EAAQ,CAAC;AAC7C,kCAAiC;AAEjC,KAAI,SAAS,SAAS,gBACpB,KAAI,OAAO,QAAQ,UAAU,WAC3B,KAAI,KACF,4GACD;KAED,KAAI;AACF,0BAAwB,QAAQ,MAAM;UAC/B,OAAO;AACd,MAAI,MAAM,wCAAwC,EAAE,OAAO,CAAC;;AAKlE,KAAI,CAAC,OAAQ,QAAO,QAAQ,SAAS;AAErC,QAAO,wBAAwB"}
1
+ {"version":3,"file":"initialize.mjs","names":[],"sources":["../../../src/core/shopify-scripts/initialize.ts"],"sourcesContent":["import { initializeCustomConsent } from \"../analytics/custom-consent\";\nimport { getLogger } from \"../logging\";\nimport { configureShopifyRouting } from \"./global\";\nimport { initializeShopifyPageViewEvents } from \"./page-view\";\nimport type { InitializeShopifyScriptsOptions } from \"./types\";\nimport { loadShopifyWebMcpTools } from \"./webmcp\";\n\nconst log = getLogger(\"consent\");\n\n/**\n * Starts Shopify's scripts in the browser for frameworks without a Hydrogen binding. Call it after\n * hydration, with the consent configuration that you passed to `getShopifyScriptTags`.\n *\n * The function sets up `window.Shopify.routes`, and sends a page view event on load and after each\n * navigation that changes the path or query. In the custom banner consent mode, Hydrogen calls your\n * setup callback after the Customer Privacy API loads. A custom banner configuration without a\n * setup callback logs a warning, and analytics events stay blocked. When the browser supports\n * WebMCP, the function also loads Shopify's WebMCP tools. Set `webMcp` to `false` to skip them.\n *\n * @param options - The consent configuration, the route settings, and whether to load WebMCP tools.\n * @returns A promise that resolves after the WebMCP tools load or fail to load, or right away when the function skips WebMCP.\n *\n * @publicDocs\n */\nexport function initializeShopifyScripts({\n consent,\n navigate,\n routes,\n webMcp = true,\n}: InitializeShopifyScriptsOptions): Promise<boolean | void> {\n configureShopifyRouting({ navigate, routes });\n initializeShopifyPageViewEvents();\n\n if (consent?.mode === \"custom-banner\") {\n if (typeof consent.setup !== \"function\") {\n log.warn(\n \"custom-banner requires a consent.setup callback; analytics delivery remains blocked until setup completes\",\n );\n } else {\n try {\n initializeCustomConsent(consent.setup);\n } catch (error) {\n log.error(\"custom consent initialization failed\", { error });\n }\n }\n }\n\n if (!webMcp) return Promise.resolve();\n\n return loadShopifyWebMcpTools();\n}\n"],"mappings":";;;;;;;AAOA,MAAM,MAAM,UAAU,UAAU;;;;;;;;;;;;;;;;AAiBhC,SAAgB,yBAAyB,EACvC,SACA,UACA,QACA,SAAS,QACkD;AAC3D,yBAAwB;EAAE;EAAU;EAAQ,CAAC;AAC7C,kCAAiC;AAEjC,KAAI,SAAS,SAAS,gBACpB,KAAI,OAAO,QAAQ,UAAU,WAC3B,KAAI,KACF,4GACD;KAED,KAAI;AACF,0BAAwB,QAAQ,MAAM;UAC/B,OAAO;AACd,MAAI,MAAM,wCAAwC,EAAE,OAAO,CAAC;;AAKlE,KAAI,CAAC,OAAQ,QAAO,QAAQ,SAAS;AAErC,QAAO,wBAAwB"}