@mercurjs/docs 2.2.1 → 2.3.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/content/home.mdx +107 -0
  2. package/content/learn/architecture.mdx +168 -83
  3. package/content/learn/introduction.mdx +161 -56
  4. package/content/learn/migration-to-2-0.mdx +187 -0
  5. package/content/learn/why-mercur.mdx +91 -0
  6. package/content/platform/attribute/concepts/attribute-types.mdx +59 -0
  7. package/content/platform/attribute/concepts/global-vs-inline.mdx +50 -0
  8. package/content/platform/attribute/concepts/variant-axes.mdx +61 -0
  9. package/content/platform/attribute/guides/attach-attributes-to-a-product.mdx +69 -0
  10. package/content/platform/attribute/guides/create-a-variant-axis.mdx +83 -0
  11. package/content/platform/attribute/guides/create-an-attribute.mdx +81 -0
  12. package/content/platform/attribute/overview.mdx +87 -0
  13. package/content/platform/attribute/reference/data-models.mdx +56 -0
  14. package/content/platform/attribute/reference/events.mdx +41 -0
  15. package/content/platform/attribute/reference/links.mdx +45 -0
  16. package/content/platform/attribute/reference/service.mdx +49 -0
  17. package/content/platform/attribute/reference/workflows.mdx +45 -0
  18. package/content/platform/catalog/concepts/master-products.mdx +54 -0
  19. package/content/platform/catalog/concepts/product-seller-allowlist.mdx +48 -0
  20. package/content/platform/catalog/concepts/status-lifecycle.mdx +58 -0
  21. package/content/platform/catalog/concepts/variants-categories-collections.mdx +49 -0
  22. package/content/platform/catalog/guides/allowlist-stores.mdx +59 -0
  23. package/content/platform/catalog/guides/create-a-master-product.mdx +70 -0
  24. package/content/platform/catalog/guides/publish-or-reject-a-product.mdx +79 -0
  25. package/content/platform/catalog/overview.mdx +90 -0
  26. package/content/platform/catalog/reference/data-models.mdx +66 -0
  27. package/content/platform/catalog/reference/events.mdx +41 -0
  28. package/content/platform/catalog/reference/links.mdx +44 -0
  29. package/content/platform/catalog/reference/service.mdx +52 -0
  30. package/content/platform/catalog/reference/workflows.mdx +40 -0
  31. package/content/platform/commission/concepts/order-commission-lines.mdx +65 -0
  32. package/content/platform/commission/concepts/rule-matching.mdx +86 -0
  33. package/content/platform/commission/concepts/rules-and-rates.mdx +84 -0
  34. package/content/platform/commission/guides/batch-update-rules.mdx +58 -0
  35. package/content/platform/commission/guides/create-a-rate.mdx +72 -0
  36. package/content/platform/commission/guides/refresh-order-commission-lines.mdx +55 -0
  37. package/content/platform/commission/overview.mdx +86 -0
  38. package/content/platform/commission/reference/data-models.mdx +75 -0
  39. package/content/platform/commission/reference/events.mdx +58 -0
  40. package/content/platform/commission/reference/links.mdx +45 -0
  41. package/content/platform/commission/reference/service.mdx +51 -0
  42. package/content/platform/commission/reference/workflows.mdx +40 -0
  43. package/content/platform/offer/concepts/pricing-and-inventory.mdx +72 -0
  44. package/content/platform/offer/concepts/shipping.mdx +48 -0
  45. package/content/platform/offer/concepts/what-is-an-offer.mdx +65 -0
  46. package/content/platform/offer/guides/bulk-create-offers.mdx +84 -0
  47. package/content/platform/offer/guides/create-an-offer.mdx +83 -0
  48. package/content/platform/offer/guides/manage-offer-inventory.mdx +53 -0
  49. package/content/platform/offer/overview.mdx +84 -0
  50. package/content/platform/offer/reference/data-models.mdx +56 -0
  51. package/content/platform/offer/reference/events.mdx +39 -0
  52. package/content/platform/offer/reference/links.mdx +60 -0
  53. package/content/platform/offer/reference/service.mdx +53 -0
  54. package/content/platform/offer/reference/workflows.mdx +38 -0
  55. package/content/platform/order-group/concepts/computed-totals.mdx +59 -0
  56. package/content/platform/order-group/concepts/order-splitting.mdx +61 -0
  57. package/content/platform/order-group/concepts/the-order-group.mdx +64 -0
  58. package/content/platform/order-group/guides/list-order-groups.mdx +67 -0
  59. package/content/platform/order-group/guides/retrieve-an-order-group.mdx +63 -0
  60. package/content/platform/order-group/guides/split-a-cart.mdx +58 -0
  61. package/content/platform/order-group/overview.mdx +83 -0
  62. package/content/platform/order-group/reference/data-models.mdx +40 -0
  63. package/content/platform/order-group/reference/events.mdx +37 -0
  64. package/content/platform/order-group/reference/links.mdx +45 -0
  65. package/content/platform/order-group/reference/service.mdx +50 -0
  66. package/content/platform/order-group/reference/workflows.mdx +39 -0
  67. package/content/platform/payout/concepts/account-lifecycle.mdx +75 -0
  68. package/content/platform/payout/concepts/accounts-and-onboarding.mdx +70 -0
  69. package/content/platform/payout/concepts/payout-pipeline.mdx +99 -0
  70. package/content/platform/payout/guides/create-a-payout-account.mdx +59 -0
  71. package/content/platform/payout/guides/process-a-provider-webhook.mdx +74 -0
  72. package/content/platform/payout/guides/start-provider-onboarding.mdx +50 -0
  73. package/content/platform/payout/overview.mdx +86 -0
  74. package/content/platform/payout/reference/data-models.mdx +61 -0
  75. package/content/platform/payout/reference/events.mdx +48 -0
  76. package/content/platform/payout/reference/links.mdx +36 -0
  77. package/content/platform/payout/reference/service.mdx +53 -0
  78. package/content/platform/payout/reference/workflows.mdx +32 -0
  79. package/content/platform/product-edit/concepts/change-actions.mdx +66 -0
  80. package/content/platform/product-edit/concepts/change-pipeline.mdx +69 -0
  81. package/content/platform/product-edit/concepts/status-and-auto-confirm.mdx +66 -0
  82. package/content/platform/product-edit/guides/confirm-or-decline-a-change.mdx +76 -0
  83. package/content/platform/product-edit/guides/edit-a-product.mdx +74 -0
  84. package/content/platform/product-edit/guides/request-a-revision.mdx +54 -0
  85. package/content/platform/product-edit/overview.mdx +85 -0
  86. package/content/platform/product-edit/reference/data-models.mdx +65 -0
  87. package/content/platform/product-edit/reference/events.mdx +47 -0
  88. package/content/platform/product-edit/reference/links.mdx +39 -0
  89. package/content/platform/product-edit/reference/service.mdx +43 -0
  90. package/content/platform/product-edit/reference/workflows.mdx +49 -0
  91. package/content/platform/review/concepts/product-vs-seller-reviews.mdx +63 -0
  92. package/content/platform/review/concepts/ratings-and-moderation.mdx +64 -0
  93. package/content/platform/review/concepts/the-review-model.mdx +56 -0
  94. package/content/platform/review/guides/compute-aggregate-ratings.mdx +57 -0
  95. package/content/platform/review/guides/create-a-review.mdx +55 -0
  96. package/content/platform/review/guides/moderate-a-review.mdx +58 -0
  97. package/content/platform/review/guides/respond-to-a-review.mdx +61 -0
  98. package/content/platform/review/overview.mdx +87 -0
  99. package/content/platform/review/reference/data-models.mdx +36 -0
  100. package/content/platform/review/reference/events.mdx +61 -0
  101. package/content/platform/review/reference/links.mdx +43 -0
  102. package/content/platform/review/reference/service.mdx +54 -0
  103. package/content/platform/review/reference/workflows.mdx +31 -0
  104. package/content/platform/store/concepts/lifecycle.mdx +62 -0
  105. package/content/platform/store/concepts/store-entity.mdx +53 -0
  106. package/content/platform/store/concepts/team.mdx +50 -0
  107. package/content/platform/store/guides/create-a-store.mdx +55 -0
  108. package/content/platform/store/guides/manage-the-team.mdx +55 -0
  109. package/content/platform/store/guides/moderate-a-store.mdx +59 -0
  110. package/content/platform/store/overview.mdx +86 -0
  111. package/content/platform/store/reference/data-models.mdx +89 -0
  112. package/content/platform/store/reference/events.mdx +43 -0
  113. package/content/platform/store/reference/links.mdx +71 -0
  114. package/content/platform/store/reference/service.mdx +51 -0
  115. package/content/platform/store/reference/workflows.mdx +35 -0
  116. package/content/references/api/admin/commission-rates/create-commission-rate.mdx +1 -1
  117. package/content/references/api/admin/commission-rates/list-commission-rates.mdx +2 -2
  118. package/content/references/api/admin/commission-rates/update-commission-rate.mdx +1 -1
  119. package/content/references/api/admin/offers/batch-create-offers.mdx +3 -3
  120. package/content/references/api/admin/order-groups/list-order-groups.mdx +1 -1
  121. package/content/references/api/admin/product-attributes/create-attribute-value.mdx +2 -2
  122. package/content/references/api/admin/product-attributes/create-product-attribute.mdx +1 -1
  123. package/content/references/api/admin/product-attributes/update-product-attribute.mdx +1 -1
  124. package/content/references/api/admin/product-changes/confirm-product-change.mdx +1 -1
  125. package/content/references/api/admin/products/batch-product-attributes.mdx +1 -1
  126. package/content/references/api/admin/products/create-product.mdx +1 -1
  127. package/content/references/api/admin/products/preview-product.mdx +1 -1
  128. package/content/references/api/admin.mdx +4 -5
  129. package/content/references/api/conventions.mdx +9 -7
  130. package/content/references/api/store/carts/add-line-item.mdx +1 -1
  131. package/content/references/api/store/offers/list-offers.mdx +1 -1
  132. package/content/references/api/store/order-groups/list-order-groups.mdx +1 -1
  133. package/content/references/api/store.mdx +4 -13
  134. package/content/references/api/vendor/members/accept-member-invite.mdx +1 -1
  135. package/content/references/api/vendor/offers/batch-create-offers.mdx +4 -0
  136. package/content/references/api/vendor/offers/batch-offer-inventory-items.mdx +2 -0
  137. package/content/references/api/vendor/offers/create-offer.mdx +13 -1
  138. package/content/references/api/vendor/offers/list-offers.mdx +4 -0
  139. package/content/references/api/vendor/offers/retrieve-offer.mdx +4 -0
  140. package/content/references/api/vendor/offers/update-offer.mdx +12 -0
  141. package/content/references/api/vendor/payout-accounts/create-onboarding.mdx +1 -1
  142. package/content/references/api/vendor/products/batch-product-attributes.mdx +1 -1
  143. package/content/references/api/vendor/products/create-product-variant.mdx +1 -1
  144. package/content/references/api/vendor/products/create-product.mdx +1 -1
  145. package/content/references/api/vendor/products/delete-product.mdx +1 -1
  146. package/content/references/api/vendor/products/update-product.mdx +1 -1
  147. package/content/references/api/vendor/sellers/create-seller.mdx +2 -2
  148. package/content/references/api/vendor/sellers/list-sellers.mdx +1 -1
  149. package/content/references/api/vendor.mdx +6 -5
  150. package/content/references/configuration.mdx +16 -33
  151. package/content/references/overview.mdx +34 -52
  152. package/content/references/panel-extensions/create-page.mdx +194 -0
  153. package/content/references/panel-extensions/custom-fields.mdx +256 -0
  154. package/content/references/panel-extensions/overview.mdx +102 -0
  155. package/content/references/panel-extensions/widgets.mdx +212 -0
  156. package/content/resources/ai/mcp.mdx +2 -2
  157. package/content/resources/ai/overview.mdx +21 -16
  158. package/content/resources/ai/skills.mdx +67 -0
  159. package/content/resources/best-practices/api-routes.mdx +55 -43
  160. package/content/resources/best-practices/custom-fields.mdx +116 -92
  161. package/content/resources/best-practices/frontend.mdx +62 -50
  162. package/content/resources/best-practices/module-links.mdx +48 -34
  163. package/content/resources/best-practices/modules.mdx +53 -27
  164. package/content/resources/best-practices/overview.mdx +45 -17
  165. package/content/resources/best-practices/subscribers-and-jobs.mdx +37 -24
  166. package/content/resources/best-practices/types.mdx +38 -23
  167. package/content/resources/best-practices/workflows.mdx +33 -21
  168. package/content/resources/customization/custom-fields.mdx +15 -15
  169. package/content/resources/customization/extend-a-workflow.mdx +7 -4
  170. package/content/resources/customization/extending-panels.mdx +55 -52
  171. package/content/resources/deployment/medusa-cloud.mdx +21 -20
  172. package/content/resources/deployment/self-host.mdx +123 -0
  173. package/content/resources/integrations/overview.mdx +38 -0
  174. package/content/resources/integrations/stripe-connect.mdx +39 -38
  175. package/content/resources/tutorials/add-a-block.mdx +25 -18
  176. package/content/resources/tutorials/add-a-widget.mdx +32 -23
  177. package/content/resources/tutorials/add-order-detail-button.mdx +33 -20
  178. package/content/resources/tutorials/attributes-and-variant-axes.mdx +28 -27
  179. package/content/resources/tutorials/build-a-block.mdx +26 -15
  180. package/content/resources/tutorials/custom-api-route.mdx +32 -20
  181. package/content/resources/tutorials/custom-panel-page.mdx +21 -12
  182. package/content/resources/tutorials/customize-navigation.mdx +30 -23
  183. package/content/resources/tutorials/extend-forms-and-tables.mdx +36 -28
  184. package/content/resources/tutorials/extend-onboarding.mdx +38 -35
  185. package/content/resources/tutorials/master-products-and-offers.mdx +28 -23
  186. package/content/telemetry.mdx +3 -3
  187. package/content/user-guide/admin/attributes/how-tos/create-an-attribute.mdx +64 -0
  188. package/content/user-guide/admin/attributes/how-tos/manage-possible-values.mdx +40 -0
  189. package/content/user-guide/admin/attributes/overview.mdx +22 -0
  190. package/content/user-guide/admin/commissions/how-tos/create-a-commission-rule.mdx +63 -0
  191. package/content/user-guide/admin/commissions/how-tos/edit-the-global-commission.mdx +48 -0
  192. package/content/user-guide/admin/commissions/how-tos/manage-a-commission-rule.mdx +45 -0
  193. package/content/user-guide/admin/commissions/overview.mdx +25 -0
  194. package/content/user-guide/admin/overview.mdx +20 -12
  195. package/content/user-guide/admin/product-requests/how-tos/review-a-new-product.mdx +58 -0
  196. package/content/user-guide/admin/product-requests/how-tos/review-a-product-edit.mdx +48 -0
  197. package/content/user-guide/admin/product-requests/overview.mdx +25 -0
  198. package/content/user-guide/vendor/offers/how-tos/create-an-offer.mdx +59 -0
  199. package/content/user-guide/vendor/offers/how-tos/update-prices-and-stock.mdx +40 -0
  200. package/content/user-guide/vendor/offers/overview.mdx +22 -0
  201. package/content/user-guide/vendor/onboarding.mdx +79 -0
  202. package/content/user-guide/vendor/orders/how-tos/fulfill-an-order.mdx +49 -0
  203. package/content/user-guide/vendor/orders/how-tos/mark-an-order-as-delivered.mdx +33 -0
  204. package/content/user-guide/vendor/orders/how-tos/process-a-return.mdx +42 -0
  205. package/content/user-guide/vendor/orders/how-tos/refund-an-order.mdx +38 -0
  206. package/content/user-guide/vendor/orders/how-tos/ship-an-order.mdx +40 -0
  207. package/content/user-guide/vendor/orders/overview.mdx +31 -0
  208. package/content/user-guide/vendor/overview.mdx +23 -12
  209. package/content/user-guide/vendor/products/how-tos/edit-a-product.mdx +44 -0
  210. package/content/user-guide/vendor/products/how-tos/submit-a-product.mdx +63 -0
  211. package/content/user-guide/vendor/products/overview.mdx +22 -0
  212. package/llms.txt +176 -142
  213. package/package.json +1 -1
  214. package/content/learn/concepts.mdx +0 -84
  215. package/content/learn/installation.mdx +0 -117
  216. package/content/learn/mirakl-alternative.mdx +0 -86
  217. package/content/migration/from-1-x-to-2-0.mdx +0 -152
  218. package/content/migration/from-2-0-to-2-1.mdx +0 -105
  219. package/content/migration/overview.mdx +0 -58
  220. package/content/references/api/store/search/search.mdx +0 -136
  221. package/content/references/modules/commission.mdx +0 -106
  222. package/content/references/modules/custom-fields.mdx +0 -45
  223. package/content/references/modules/media.mdx +0 -55
  224. package/content/references/modules/offer.mdx +0 -64
  225. package/content/references/modules/payout.mdx +0 -121
  226. package/content/references/modules/product-attribute.mdx +0 -111
  227. package/content/references/modules/product-edit.mdx +0 -80
  228. package/content/references/modules/search.mdx +0 -112
  229. package/content/references/modules/seller.mdx +0 -175
  230. package/content/references/panel-extension-api.mdx +0 -337
  231. package/content/references/workflows/cart/add-seller-shipping-method-to-cart.mdx +0 -48
  232. package/content/references/workflows/cart/complete-cart-with-split-orders.mdx +0 -36
  233. package/content/references/workflows/cart/list-seller-shipping-options-for-cart.mdx +0 -39
  234. package/content/references/workflows/cart/update-cart-seller-promotions.mdx +0 -42
  235. package/content/references/workflows/commission/batch-commission-rules.mdx +0 -49
  236. package/content/references/workflows/commission/create-commission-rates.mdx +0 -41
  237. package/content/references/workflows/commission/delete-commission-rates.mdx +0 -34
  238. package/content/references/workflows/commission/refresh-order-commission-lines.mdx +0 -30
  239. package/content/references/workflows/commission/update-commission-rates.mdx +0 -35
  240. package/content/references/workflows/media/set-category-images.mdx +0 -41
  241. package/content/references/workflows/media/set-collection-images.mdx +0 -41
  242. package/content/references/workflows/member/accept-member-invite.mdx +0 -33
  243. package/content/references/workflows/member/add-seller-member.mdx +0 -30
  244. package/content/references/workflows/member/create-member-invites.mdx +0 -34
  245. package/content/references/workflows/member/delete-member-invite.mdx +0 -24
  246. package/content/references/workflows/member/remove-seller-member.mdx +0 -28
  247. package/content/references/workflows/member/resend-member-invite.mdx +0 -28
  248. package/content/references/workflows/member/update-member-role.mdx +0 -28
  249. package/content/references/workflows/member/update-member.mdx +0 -35
  250. package/content/references/workflows/offer/batch-offer-inventory-items.mdx +0 -62
  251. package/content/references/workflows/offer/create-offers.mdx +0 -65
  252. package/content/references/workflows/offer/delete-offers.mdx +0 -35
  253. package/content/references/workflows/offer/update-offers.mdx +0 -53
  254. package/content/references/workflows/order/cancel-order-fulfillment.mdx +0 -34
  255. package/content/references/workflows/order/confirm-claim-request.mdx +0 -25
  256. package/content/references/workflows/order/confirm-exchange-request.mdx +0 -25
  257. package/content/references/workflows/order/confirm-order-edit-request.mdx +0 -25
  258. package/content/references/workflows/order/confirm-return-receive.mdx +0 -25
  259. package/content/references/workflows/order/create-order-fulfillment.mdx +0 -45
  260. package/content/references/workflows/order-group/get-order-group-detail.mdx +0 -29
  261. package/content/references/workflows/order-group/get-order-groups-list.mdx +0 -38
  262. package/content/references/workflows/overview.mdx +0 -72
  263. package/content/references/workflows/payout/create-onboarding.mdx +0 -36
  264. package/content/references/workflows/payout/create-payout-account.mdx +0 -33
  265. package/content/references/workflows/payout/create-payout.mdx +0 -30
  266. package/content/references/workflows/payout/process-payout-for-webhook.mdx +0 -34
  267. package/content/references/workflows/product/confirm-products.mdx +0 -48
  268. package/content/references/workflows/product/create-products.mdx +0 -63
  269. package/content/references/workflows/product/link-sellers-to-product-category.mdx +0 -40
  270. package/content/references/workflows/product/link-sellers-to-product.mdx +0 -40
  271. package/content/references/workflows/product/reject-product.mdx +0 -48
  272. package/content/references/workflows/product/request-product-change.mdx +0 -48
  273. package/content/references/workflows/product-attribute/add-product-attributes-to-product.mdx +0 -49
  274. package/content/references/workflows/product-attribute/create-and-link-product-attributes-to-product.mdx +0 -46
  275. package/content/references/workflows/product-attribute/create-product-attribute-values.mdx +0 -43
  276. package/content/references/workflows/product-attribute/create-product-attributes.mdx +0 -56
  277. package/content/references/workflows/product-attribute/delete-product-attribute-values.mdx +0 -30
  278. package/content/references/workflows/product-attribute/delete-product-attributes.mdx +0 -30
  279. package/content/references/workflows/product-attribute/remove-product-attributes-from-product.mdx +0 -29
  280. package/content/references/workflows/product-attribute/update-product-attribute-values.mdx +0 -44
  281. package/content/references/workflows/product-attribute/update-product-attributes-on-product.mdx +0 -41
  282. package/content/references/workflows/product-attribute/update-product-attributes.mdx +0 -48
  283. package/content/references/workflows/product-attribute/upsert-product-attribute-values.mdx +0 -43
  284. package/content/references/workflows/product-edit/auto-confirm-product-change.mdx +0 -39
  285. package/content/references/workflows/product-edit/cancel-product-change.mdx +0 -49
  286. package/content/references/workflows/product-edit/confirm-product-change.mdx +0 -57
  287. package/content/references/workflows/product-edit/create-product-change.mdx +0 -72
  288. package/content/references/workflows/product-edit/reject-product-change.mdx +0 -54
  289. package/content/references/workflows/product-edit/stage-product-change.mdx +0 -75
  290. package/content/references/workflows/seller/approve-seller.mdx +0 -36
  291. package/content/references/workflows/seller/create-seller-account.mdx +0 -59
  292. package/content/references/workflows/seller/create-seller-defaults.mdx +0 -22
  293. package/content/references/workflows/seller/create-sellers.mdx +0 -65
  294. package/content/references/workflows/seller/delete-seller-professional-details.mdx +0 -37
  295. package/content/references/workflows/seller/delete-sellers.mdx +0 -24
  296. package/content/references/workflows/seller/invite-seller.mdx +0 -28
  297. package/content/references/workflows/seller/suspend-seller.mdx +0 -37
  298. package/content/references/workflows/seller/terminate-seller.mdx +0 -37
  299. package/content/references/workflows/seller/unsuspend-seller.mdx +0 -36
  300. package/content/references/workflows/seller/unterminate-seller.mdx +0 -36
  301. package/content/references/workflows/seller/update-seller-address.mdx +0 -55
  302. package/content/references/workflows/seller/update-seller-payment-details.mdx +0 -52
  303. package/content/references/workflows/seller/update-seller-professional-details.mdx +0 -48
  304. package/content/references/workflows/seller/update-sellers.mdx +0 -57
  305. package/content/resources/ai/llms.mdx +0 -74
  306. package/content/resources/integrations/notifications.mdx +0 -39
  307. package/content/resources/integrations/search.mdx +0 -122
  308. package/content/resources/tutorials/configure-commissions.mdx +0 -127
  309. package/content/resources/tutorials/first-marketplace.mdx +0 -45
  310. package/content/resources/tutorials/handle-product-requests.mdx +0 -80
  311. package/content/resources/tutorials/import-export-products.mdx +0 -96
  312. package/content/resources/tutorials/seller-payouts-stripe.mdx +0 -89
  313. package/content/resources/tutorials/store-setup-checklist.mdx +0 -214
  314. package/content/tools/api-client.mdx +0 -155
  315. package/content/tools/cli.mdx +0 -196
  316. package/content/tools/dashboard-sdk.mdx +0 -35
@@ -1,21 +1,24 @@
1
1
  ---
2
- title: "Customize navigation"
3
- description: "Reorder, hide, relabel, and re-parent built-in sidebar items with a single _navigation.ts file and defineNavigationConfig."
2
+ title: "How to Customize Navigation"
3
+ sidebarTitle: "Customize Navigation"
4
+ description: "Reorder, hide, relabel, and re-parent the panel's built-in sidebar items from a single _navigation.ts file."
4
5
  ---
5
6
 
6
- The built-in sidebar ships a fixed set of items — Orders, Products, Customers, and so on. To reshape them without replacing the whole sidebar, author one host-owned file: `src/_navigation.ts`. It reorders, hides, relabels, and re-parents **built-in** items, and it is the single source of truth for the sidebar's shape.
7
+ Reshape the built-in sidebar without replacing it. You author one host-owned file, `src/_navigation.ts`, and it reorders, hides, relabels, and re-parents the built-in items.
8
+
9
+ The sidebar ships a fixed set of items such as Orders, Products, and Customers. `_navigation.ts` is the single source of truth for their shape. It overrides existing items only, so a new item still comes from a page you add.
7
10
 
8
11
  <Info>
9
- **When to use this vs. a `config` export.** New pages you add via [drop-in routes](/rc/resources/tutorials/custom-panel-page) place their own sidebar item through `defineRouteConfig({ label, rank, nested })`. `_navigation.ts` is for the items you *didn't* create the built-in ones. The two layer cleanly: custom routes place themselves; `_navigation.ts` reshapes the built-ins.
12
+ **When to use this vs. a `config` export.** New pages you add via [drop-in routes](/rc/resources/tutorials/custom-panel-page) place their own sidebar item through `defineRouteConfig({ label, rank, nested })`. `_navigation.ts` is for the items you *didn't* create, the built-in ones. The two layer cleanly: custom routes place themselves, and `_navigation.ts` reshapes the built-ins.
10
13
  </Info>
11
14
 
12
15
  ## What you'll build
13
16
 
14
17
  A vendor sidebar with Orders pinned to the top, Price Lists hidden, and Campaigns moved under Orders.
15
18
 
16
- ## Register the typed targets (once)
19
+ ## Register the typed targets
17
20
 
18
- Nav item ids are typed and generated per panel. Register them once with a single ambient reference in your app's `src` (already shipped by `create-mercur-app`):
21
+ Nav item ids are typed and generated per panel. Register them once with a single ambient reference in your app's `src`. The `create-mercur-app` scaffold already ships this file.
19
22
 
20
23
  ```typescript apps/vendor/src/extension-targets.d.ts
21
24
  /// <reference types="@mercurjs/vendor/extension-targets" />
@@ -27,7 +30,7 @@ With it present, `id` and `nested` autocomplete and an unknown id fails `tsc`.
27
30
 
28
31
  <Steps>
29
32
  <Step title="Create src/_navigation.ts">
30
- The file is host-owned and underscore-prefixed. Default-export a `defineNavigationConfig` with an `items` array of overrides:
33
+ The file is host-owned and underscore-prefixed. Default-export a `defineNavigationConfig` with an `items` array of overrides.
31
34
 
32
35
  ```ts apps/vendor/src/_navigation.ts
33
36
  import { defineNavigationConfig } from "@mercurjs/dashboard-sdk"
@@ -42,21 +45,25 @@ With it present, `id` and `nested` autocomplete and an unknown id fails `tsc`.
42
45
  ```
43
46
  </Step>
44
47
  <Step title="Know the override fields">
45
- Each entry targets one built-in item by its stable `id`:
48
+ Each entry targets one built-in item by its stable `id`.
46
49
 
47
50
  | Field | Type | Effect |
48
51
  |-------|------|--------|
49
- | `id` | `NavItemId` | **Required.** The built-in item to override (top-level or nested) |
50
- | `rank` | `number` | Order within its parent (lower first) |
51
- | `hidden` | `boolean` | Remove it from the sidebar |
52
- | `label` | `string` | Relabel (i18n key or literal) |
53
- | `icon` | `ComponentType` | Replace its icon |
54
- | `nested` | `NavParentId \| null` | Re-parent under another top-level item; `null` promotes a nested item to top level |
55
-
56
- Both `id` and `nested` are checked against the panel's generated `NavItemRegistry` / `NavParentRegistry`.
52
+ | `id` | `NavItemId` | **Required.** The built-in item to override, top-level or nested. |
53
+ | `rank` | `number` | Order within its parent, lower first. |
54
+ | `hidden` | `boolean` | Remove it from the sidebar. |
55
+ | `label` | `string` | Relabel with an i18n key or literal. |
56
+ | `icon` | `ComponentType` | Replace its icon. |
57
+ | `nested` | `NavParentId \| null` | Re-parent under another top-level item. `null` promotes a nested item to top level. |
58
+
59
+ Both `id` and `nested` are checked against the panel's generated `NavItemRegistry` and `NavParentRegistry`.
57
60
  </Step>
58
61
  <Step title="Reload the panel">
59
- Open the vendor portal Orders sits at the top, Price Lists is gone from the menu, and Campaigns now appears under Orders. The route for a hidden item stays reachable directly by URL unless you also remove it.
62
+ Open the vendor portal. Orders sits at the top, Price Lists is gone from the menu, and Campaigns now appears under Orders.
63
+
64
+ <Note>
65
+ The route for a hidden item stays reachable directly by URL unless you also remove it.
66
+ </Note>
60
67
  </Step>
61
68
  </Steps>
62
69
 
@@ -78,23 +85,23 @@ export default defineNavigationConfig({
78
85
  1. The top-level order reflects your `rank` values, with `orders` first.
79
86
  2. `price-lists` no longer appears in the sidebar.
80
87
  3. `campaigns` renders as a child under Orders.
81
- 4. Set `id: "not-an-item"` `bun run lint` (tsc) fails against `NavItemRegistry`.
82
- 5. Delete `_navigation.ts` the default sidebar returns.
88
+ 4. Set `id: "not-an-item"`. `bun run lint` (tsc) fails against `NavItemRegistry`.
89
+ 5. Delete `_navigation.ts`. The default sidebar returns.
83
90
 
84
91
  ## FAQ
85
92
 
86
93
  <AccordionGroup>
87
94
  <Accordion title="Can an installed block reorder the sidebar?">
88
- No. Navigation is deliberately host-only blocks can ship pages, widgets, and custom fields, but the sidebar order stays a single source of truth in your app's `_navigation.ts`.
95
+ No. Navigation is deliberately host-only. Blocks can ship pages, widgets, and custom fields, but the sidebar order stays a single source of truth in your app's `_navigation.ts`.
89
96
  </Accordion>
90
97
  <Accordion title="What ids can I target?">
91
- Any built-in item, top-level or nested, by its own id e.g. `orders`, `products`, `categories`, `collections`, `campaigns`, `customer-groups`. Let your editor autocomplete `id:` against `NavItemId`; the full set is generated into your panel's `extension-targets.d.ts`.
98
+ Any built-in item, top-level or nested, by its own id, such as `orders`, `products`, `categories`, `collections`, `campaigns`, or `customer-groups`. Let your editor autocomplete `id:` against `NavItemId`. The full set is generated into your panel's `extension-targets.d.ts`.
92
99
  </Accordion>
93
100
  <Accordion title="Does this work in the admin panel too?">
94
- Yes drop `src/_navigation.ts` in the admin app and reference `@mercurjs/admin/extension-targets`. Each panel ships its own nav id set.
101
+ Yes. Drop `src/_navigation.ts` in the admin app and reference `@mercurjs/admin/extension-targets`. Each panel ships its own nav id set.
95
102
  </Accordion>
96
103
  <Accordion title="How do I add a brand-new sidebar item?">
97
- That's a [drop-in route](/rc/resources/tutorials/custom-panel-page) with a `config` export `_navigation.ts` only reshapes built-in items, it doesn't create routes.
104
+ That's a [drop-in route](/rc/resources/tutorials/custom-panel-page) with a `config` export. `_navigation.ts` only reshapes built-in items, it doesn't create routes.
98
105
  </Accordion>
99
106
  </AccordionGroup>
100
107
 
@@ -1,21 +1,22 @@
1
1
  ---
2
- title: "Extend forms and tables"
3
- description: "Add validated fields to built-in forms, replace fields in detail sections, and add list columns with defineCustomFieldsConfig and createFormHelper."
2
+ title: "How to Extend Forms and Tables"
3
+ sidebarTitle: "Extend Forms & Tables"
4
+ description: "Add validated fields, detail-section displays, and list columns to a built-in model from a single file with defineCustomFieldsConfig."
4
5
  ---
5
6
 
6
- `defineCustomFieldsConfig` is Mercur's model-scoped extension surface: from one file per model, you add validated fields to built-in create/edit forms, replace/remove/add fields in detail sections, and add columns to the list table all wired into the built-in page, all typed against the model's generated registry.
7
+ `defineCustomFieldsConfig` is Mercur's model-scoped extension surface. From one file per model you add validated fields to built-in create and edit forms, replace, remove, or add fields in detail sections, and add columns to the list table. Everything wires into the built-in page and stays typed against the model's generated registry.
7
8
 
8
9
  <Info>
9
- **UI, not schema.** This helper is a *panel* surface it renders, validates, and displays fields. It does not create database columns. To *store* extra data, use the backend [Custom Fields module](/rc/resources/customization/custom-fields) or your own API route/workflow. In the MVP, panel custom fields for `product` are submitted under `additional_data` and persisted onto the product's `metadata`.
10
+ **UI, not schema.** This helper is a panel surface. It renders, validates, and displays fields. It does not create database columns. To store extra data, use the backend [Custom Fields module](/rc/resources/customization/custom-fields) or your own API route or workflow. In the MVP, panel custom fields for `product` are submitted under `additional_data` and persisted onto the product's `metadata`.
10
11
  </Info>
11
12
 
12
13
  ## What you'll build
13
14
 
14
- An `ERP ID` field on the vendor product edit form, shown in the product's detail section and as a list-table column from a single `src/custom-fields/product.tsx`.
15
+ An `ERP ID` field on the vendor product edit form, shown in the product's detail section and as a list-table column, all from a single `src/custom-fields/product.tsx`.
15
16
 
16
- ## Register the typed targets (once)
17
+ ## Register the typed targets
17
18
 
18
- Models, form zones, display zones, and built-in field ids are typed per panel. Register them once (shipped by `create-mercur-app`):
19
+ Models, form zones, display zones, and built-in field ids are typed per panel. You register them once, and `create-mercur-app` ships this reference for you.
19
20
 
20
21
  ```typescript apps/vendor/src/extension-targets.d.ts
21
22
  /// <reference types="@mercurjs/vendor/extension-targets" />
@@ -25,7 +26,7 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
25
26
 
26
27
  <Steps>
27
28
  <Step title="Create the model file">
28
- Drop `src/custom-fields/<model>.tsx` and default-export a `defineCustomFieldsConfig`. `createFormHelper` (from `@mercurjs/dashboard-shared`) turns a Zod schema into an input type + validation:
29
+ Drop `src/custom-fields/<model>.tsx` and default-export a `defineCustomFieldsConfig`. `createFormHelper` from `@mercurjs/dashboard-shared` turns a Zod schema into an input type plus validation.
29
30
 
30
31
  ```tsx apps/vendor/src/custom-fields/product.tsx
31
32
  import { defineCustomFieldsConfig } from "@mercurjs/dashboard-sdk"
@@ -53,10 +54,11 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
53
54
  })
54
55
  ```
55
56
  </Step>
57
+
56
58
  <Step title="Add a detail-section display">
57
- `displays[]` targets a detail-page section by its `zone` id. Keyed by field `id`, an entry **adds**, **replaces**, or **removes** a field:
59
+ `displays[]` targets a detail-page section by its `zone` id. Keyed by field `id`, an entry adds, replaces, or removes a field.
58
60
 
59
- ```tsx
61
+ ```tsx apps/vendor/src/custom-fields/product.tsx
60
62
  import { Text } from "@medusajs/ui"
61
63
 
62
64
  // ...inside defineCustomFieldsConfig:
@@ -64,7 +66,7 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
64
66
  {
65
67
  zone: "general",
66
68
  fields: [
67
- // ADD an unknown id appends a new read-only row
69
+ // ADD: an unknown id appends a new read-only row
68
70
  {
69
71
  id: "erp_id",
70
72
  component: ({ data }) => (
@@ -73,9 +75,9 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
73
75
  </Text>
74
76
  ),
75
77
  },
76
- // REMOVE a built-in id + null hides the field
78
+ // REMOVE: a built-in id + null hides the field
77
79
  { id: "subtitle", component: null },
78
- // REPLACE a built-in id + component overrides its render
80
+ // REPLACE: a built-in id + component overrides its render
79
81
  {
80
82
  id: "handle",
81
83
  component: ({ data }) => (
@@ -89,12 +91,15 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
89
91
  ],
90
92
  ```
91
93
 
92
- Built-in field ids (like `subtitle`, `handle`, `status`, `title`) autocomplete from the panel's generated `CustomFieldsRegistry`; an unknown id is treated as an added row.
94
+ <Tip>
95
+ Built-in field ids such as `subtitle`, `handle`, `status`, and `title` autocomplete from the panel's generated `CustomFieldsRegistry`. An unknown id is treated as an added row.
96
+ </Tip>
93
97
  </Step>
98
+
94
99
  <Step title="Add a list column">
95
- The `list` block extends the model's list table add or override columns by id, hide built-in columns, and reorder:
100
+ The `list` block extends the model's list table. Add or override columns by id, hide built-in columns, and reorder.
96
101
 
97
- ```tsx
102
+ ```tsx apps/vendor/src/custom-fields/product.tsx
98
103
  // ...inside defineCustomFieldsConfig:
99
104
  list: {
100
105
  columns: [
@@ -111,14 +116,15 @@ Models, form zones, display zones, and built-in field ids are typed per panel. R
111
116
  },
112
117
  ```
113
118
  </Step>
119
+
114
120
  <Step title="Reload the panel">
115
- Open the vendor portal. The product **edit** drawer shows the ERP ID field (validated on submit and persisted via `additional_data`), the detail **general** section shows the ERP ID row (with `subtitle` removed and `handle` re-rendered), and the product **list** shows the ERP column.
121
+ Open the vendor portal. The product edit drawer shows the ERP ID field, validated on submit and persisted via `additional_data`. The detail general section shows the ERP ID row, with `subtitle` removed and `handle` re-rendered. The product list shows the ERP column.
116
122
  </Step>
117
123
  </Steps>
118
124
 
119
- ## The `createFormHelper` surface
125
+ ## The createFormHelper surface
120
126
 
121
- `createFormHelper<T>()` exposes a Zod-based surface that drives both the input type and its validation:
127
+ `createFormHelper<T>()` exposes a Zod-based surface that drives both the input type and its validation.
122
128
 
123
129
  ```ts
124
130
  const form = createFormHelper<T>()
@@ -133,11 +139,11 @@ form.define({
133
139
  })
134
140
  ```
135
141
 
136
- Fields render through the standard `Form.Field → Form.Item` chain (never a raw `Controller`) and participate in the existing `TabbedForm` / `RouteDrawer` submit and validation flow.
142
+ Fields render through the standard `Form.Field → Form.Item` chain, never a raw `Controller`. They participate in the existing `TabbedForm` and `RouteDrawer` submit and validation flow.
137
143
 
138
144
  ## Linked-module data
139
145
 
140
- To read data from a linked module alongside the entity, declare it with `link`; those relations are fetched with the entity and become available to columns and displays:
146
+ To read data from a linked module alongside the entity, declare it with `link`. Those relations are fetched with the entity and become available to columns and displays.
141
147
 
142
148
  ```ts
143
149
  export default defineCustomFieldsConfig({
@@ -149,30 +155,32 @@ export default defineCustomFieldsConfig({
149
155
  })
150
156
  ```
151
157
 
152
- The SDK derives the fetch query from `link` and merges it into the built-in query with the `+`/`-` convention — you never hand-write the field list.
158
+ <Note>
159
+ The SDK derives the fetch query from `link` and merges it into the built-in query with the `+` and `-` convention. You never hand-write the field list.
160
+ </Note>
153
161
 
154
162
  ## Verify
155
163
 
156
164
  1. The ERP ID field renders in the product edit drawer and validates on submit.
157
- 2. Saving persists the value (visible on reload) via `additional_data` `metadata`.
165
+ 2. Saving persists the value, visible on reload, via `additional_data` to `metadata`.
158
166
  3. The detail general section shows the ERP row, hides `subtitle`, and re-renders `handle`.
159
167
  4. The product list shows the ERP column, hides `collection`, and reorders columns.
160
- 5. Set `zone: "nope"` in `forms` `bun run lint` (tsc) fails against the model's registry.
168
+ 5. Set `zone: "nope"` in `forms`. `bun run lint` (tsc) fails against the model's registry.
161
169
 
162
170
  ## FAQ
163
171
 
164
172
  <AccordionGroup>
165
173
  <Accordion title="Which models and zones are available?">
166
- Today: the `product` model in the vendor portal, with form zone `edit` and display zone `general`. The valid set per panel is generated into `CustomFieldsRegistry` in `extension-targets.d.ts` autocomplete `model` / `zone` to see what's mounted.
174
+ Today: the `product` model in the vendor portal, with form zone `edit` and display zone `general`. The valid set per panel is generated into `CustomFieldsRegistry` in `extension-targets.d.ts`. Autocomplete `model` and `zone` to see what's mounted.
167
175
  </Accordion>
168
176
  <Accordion title="Where is the value actually stored?">
169
- In the MVP, product custom fields are submitted under `additional_data` and persisted onto `product.metadata`. `defineCustomFieldsConfig` itself doesn't create a column for durable, queryable storage model it with the backend [Custom Fields module](/rc/resources/customization/custom-fields) or a custom route/workflow.
177
+ In the MVP, product custom fields are submitted under `additional_data` and persisted onto `product.metadata`. `defineCustomFieldsConfig` itself doesn't create a column. For durable, queryable storage, model it with the backend [Custom Fields module](/rc/resources/customization/custom-fields) or a custom route or workflow.
170
178
  </Accordion>
171
179
  <Accordion title="Can I extend the onboarding wizard?">
172
- That's the same helper with `zone: "onboarding"` and `tab` set to a wizard step id (vendor only). It's designed but not mounted in the current MVP the runtime host exists; the wizard mount is a follow-up.
180
+ That's the same helper with `zone: "onboarding"` and `tab` set to a wizard step id (vendor only). It's designed but not mounted in the current MVP. The runtime host exists. The wizard mount is a follow-up.
173
181
  </Accordion>
174
182
  <Accordion title="Can a block ship custom fields?">
175
- Yes a [block](/rc/learn/blocks) can include `src/custom-fields/` files in its `vendor_ui` / `admin_ui` entry, aggregated like the host app's.
183
+ Yes. A [block](/rc/learn/blocks) can include `src/custom-fields/` files in its `vendor_ui` or `admin_ui` entry, aggregated like the host app's.
176
184
  </Accordion>
177
185
  </AccordionGroup>
178
186
 
@@ -1,21 +1,24 @@
1
1
  ---
2
- title: "Extend the onboarding flow"
3
- description: "Add a field to the vendor store-setup surface, submit it through additional_data, and persist it durably from a workflow hook — end to end, without forking."
2
+ title: "How to Extend Onboarding"
3
+ sidebarTitle: "Extend Onboarding"
4
+ description: "Add a field to the vendor store-setup surface, carry it through additional_data, and persist it from a workflow hook without forking core."
4
5
  ---
5
6
 
6
- The vendor **store-setup / onboarding** surface is a widget zone (`seller.setup`) that renders the full `seller` object as its `data`. That makes onboarding a full extension seam: drop a widget to add UI, carry the new value to the API on the built-in seller routes through `additional_data`, and persist it from a workflow hook — the same three layers you'd wire in plain Medusa, kept intact by Mercur.
7
+ Add a custom field to the vendor onboarding flow and store its value durably, end to end.
8
+
9
+ The vendor store-setup and onboarding surface is a widget zone, `seller.setup`, that renders the full `seller` object as its `data`. That makes onboarding a full extension seam. You drop a widget to add UI, carry the new value to the API on the built-in seller routes through `additional_data`, and persist it from a workflow hook. These are the same three layers you wire in plain Medusa, kept intact by Mercur.
7
10
 
8
11
  <Info>
9
- **Three layers, one flow.** The panel (a `seller.setup` widget) *renders and collects*. The vendor seller route *carries* the value through `additional_data` no core schema change. A `sellersUpdated` workflow hook *persists* it. Each layer is additive: nothing built-in is replaced.
12
+ **Three layers, one flow.** The panel, a `seller.setup` widget, renders and collects. The vendor seller route carries the value through `additional_data` with no core schema change. A `sellersUpdated` workflow hook persists it. Each layer is additive: nothing built-in is replaced.
10
13
  </Info>
11
14
 
12
- ## What you'll build
15
+ ## What you build
13
16
 
14
- A "Tax ID" prompt on the vendor store-setup surface. The vendor types a VAT number; it rides `additional_data` to `POST /vendor/sellers/:id`, and a workflow hook stores it durably through the [Custom Fields module](/rc/resources/customization/custom-fields).
17
+ A "Tax ID" prompt on the vendor store-setup surface. The vendor types a VAT number. It rides `additional_data` to `POST /vendor/sellers/:id`, and a workflow hook stores it durably through the [Custom Fields module](/rc/resources/customization/custom-fields).
15
18
 
16
- ## Register the typed targets (once)
19
+ ## Register the typed targets
17
20
 
18
- Widget zones are typed ids the vendor panel generates from its own pages and ships as `@mercurjs/vendor/extension-targets`. Register them once (shipped by `create-mercur-app`):
21
+ Widget zones are typed ids the vendor panel generates from its own pages and ships as `@mercurjs/vendor/extension-targets`. Register them once. `create-mercur-app` ships this file for you.
19
22
 
20
23
  ```typescript apps/vendor/src/extension-targets.d.ts
21
24
  /// <reference types="@mercurjs/vendor/extension-targets" />
@@ -23,11 +26,11 @@ Widget zones are typed ids the vendor panel generates from its own pages and shi
23
26
 
24
27
  With it present, `seller.setup` autocompletes and an invalid zone fails `tsc` instead of silently doing nothing.
25
28
 
26
- ## 1 — Render on the onboarding surface
29
+ ## Render on the onboarding surface
27
30
 
28
31
  <Steps>
29
32
  <Step title="Add the store-setup widget">
30
- Drop a file under `src/widgets/`. Export the component as the **default** and a `config` with `zone: "seller.setup.before"`. The zone hands your component the `seller` as `data`:
33
+ Drop a file under `src/widgets/`. Export the component as the **default** and a `config` with `zone: "seller.setup.before"`. The zone hands your component the `seller` as `data`.
31
34
 
32
35
  ```tsx apps/vendor/src/widgets/tax-id-setup.tsx
33
36
  import "@mercurjs/vendor/extension-targets"
@@ -50,7 +53,7 @@ With it present, `seller.setup` autocompletes and an invalid zone fails `tsc` in
50
53
  mutationFn: () =>
51
54
  client.vendor.sellers.$id.mutate({
52
55
  $id: seller!.id,
53
- // additional_data is accepted on every vendor seller route
56
+ // additional_data is accepted on every vendor seller route.
54
57
  // it never touches the built-in seller columns.
55
58
  additional_data: { tax_id: taxId },
56
59
  }),
@@ -94,26 +97,26 @@ With it present, `seller.setup` autocompletes and an invalid zone fails `tsc` in
94
97
  ```
95
98
  </Step>
96
99
  <Step title="Understand where it renders">
97
- `seller.setup` is hosted in two places, both passing the same `seller` as `data`:
100
+ `seller.setup` is hosted in two places, both passing the same `seller` as `data`.
98
101
 
99
102
  | Host | When it shows |
100
103
  |------|---------------|
101
- | The vendor shell (above the page outlet) | On top-level routes the dashboard "home" onboarding banner |
104
+ | The vendor shell (above the page outlet) | On top-level routes (the dashboard "home" onboarding banner) |
102
105
  | The store settings detail page | Always, above the store status banner |
103
106
 
104
- A single widget file covers both. Multiple `seller.setup.before` / `.after` widgets stack in registration order.
107
+ A single widget file covers both. Multiple `seller.setup.before` and `.after` widgets stack in registration order.
105
108
  </Step>
106
109
  </Steps>
107
110
 
108
111
  <Note>
109
- **`client` is your app's typed SDK.** `create-mercur-app` ships `apps/vendor/src/lib/client.ts` a `createClient<Routes>()` instance. `client.vendor.sellers.$id.mutate(...)` is the typed `POST /vendor/sellers/:id`, so the request and response types match the backend route.
112
+ **`client` is your app's typed SDK.** `create-mercur-app` ships `apps/vendor/src/lib/client.ts`, a `createClient<Routes>()` instance. `client.vendor.sellers.$id.mutate(...)` is the typed `POST /vendor/sellers/:id`, so the request and response types match the backend route.
110
113
  </Note>
111
114
 
112
- ## 2 — Carry the value through `additional_data`
115
+ ## Carry the value through additional_data
113
116
 
114
- You don't touch the seller route or its validator. Every vendor and admin seller route already wraps its body with `WithAdditionalData`, so an unknown `additional_data` object is accepted and forwarded into the workflow untouched:
117
+ You don't touch the seller route or its validator. Every vendor and admin seller route already wraps its body with `WithAdditionalData`, so an unknown `additional_data` object is accepted and forwarded into the workflow untouched.
115
118
 
116
- ```ts packages/core/src/api/vendor/sellers/[id]/route.ts (built-in — for reference)
119
+ ```ts packages/core/src/api/vendor/sellers/[id]/route.ts
117
120
  const { additional_data, ...update } = req.validatedBody
118
121
 
119
122
  await updateSellersWorkflow(req.scope).run({
@@ -125,15 +128,15 @@ await updateSellersWorkflow(req.scope).run({
125
128
  })
126
129
  ```
127
130
 
128
- That is the whole "wiring" step: your `{ tax_id }` payload arrives in the workflow as `additional_data` without a schema change.
131
+ That is the whole wiring step. Your `{ tax_id }` payload arrives in the workflow as `additional_data` without a schema change.
129
132
 
130
- ## 3 — Persist it from a workflow hook
133
+ ## Persist it from a workflow hook
131
134
 
132
135
  `updateSellersWorkflow` exposes a `sellersUpdated` hook that runs after the update with `{ sellers, additional_data }`. Subscribe to it in your Medusa app and persist the value.
133
136
 
134
137
  <Steps>
135
138
  <Step title="Declare a durable field">
136
- Register a `Seller` custom field so the value gets a real, queryable column (no migration to hand-write):
139
+ Register a `Seller` custom field so the value gets a real, queryable column. No migration to hand-write.
137
140
 
138
141
  ```ts apps/api/medusa-config.ts
139
142
  module.exports = defineConfig({
@@ -153,12 +156,12 @@ That is the whole "wiring" step: your `{ tax_id }` payload arrives in the workfl
153
156
  })
154
157
  ```
155
158
 
156
- ```bash
159
+ ```bash Terminal
157
160
  bunx medusa db:migrate
158
161
  ```
159
162
  </Step>
160
163
  <Step title="Subscribe to the hook">
161
- Drop a file under `src/workflows/` in your Medusa app. Medusa imports everything under `src/workflows` at boot, so registering the hook is just defining it. Read `additional_data`, upsert through the Custom Fields service:
164
+ Drop a file under `src/workflows/` in your Medusa app. Medusa imports everything under `src/workflows` at boot, so registering the hook is just defining it. Read `additional_data` and upsert through the Custom Fields service.
162
165
 
163
166
  ```ts apps/api/src/workflows/hooks/seller-tax-id.ts
164
167
  import { updateSellersWorkflow } from "@mercurjs/core/workflows"
@@ -182,11 +185,11 @@ That is the whole "wiring" step: your `{ tax_id }` payload arrives in the workfl
182
185
  ```
183
186
 
184
187
  <Tip>
185
- The hook fires for **every** seller update, not only your widget's always guard on the field being present (`typeof taxId !== "string"`) so unrelated edits (name, address, status) pass through untouched.
188
+ The hook fires for **every** seller update, not only your widget's. Always guard on the field being present (`typeof taxId !== "string"`) so unrelated edits, such as name, address, or status, pass through untouched.
186
189
  </Tip>
187
190
  </Step>
188
191
  <Step title="Read it back">
189
- The value is now linked to the seller and queryable through Medusa's remote query:
192
+ The value is now linked to the seller and queryable through Medusa's remote query.
190
193
 
191
194
  ```ts
192
195
  const { data: [seller] } = await query.graph({
@@ -217,27 +220,27 @@ seller.custom_fields.tax_id (durable, queryable)
217
220
 
218
221
  ## Verify
219
222
 
220
- 1. Open the vendor portal the Tax ID prompt renders on the dashboard home and on **Settings → Store**.
221
- 2. Enter a value and save the mutation succeeds (`toast.success`) and hits `POST /vendor/sellers/:id`.
223
+ 1. Open the vendor portal. The Tax ID prompt renders on the dashboard home and on **Settings → Store**.
224
+ 2. Enter a value and save. The mutation succeeds (`toast.success`) and hits `POST /vendor/sellers/:id`.
222
225
  3. `query.graph({ entity: "seller", fields: ["custom_fields.tax_id"] })` returns the saved value.
223
- 4. Edit an unrelated field (store name) the seller update still works and the guard skips the upsert.
224
- 5. Set `zone: "not.a.zone"` on the widget `bun run lint` (tsc) fails against `WidgetZoneId`.
225
- 6. Delete the widget file the prompt disappears; the seller route and hook are unaffected.
226
+ 4. Edit an unrelated field, such as store name. The seller update still works and the guard skips the upsert.
227
+ 5. Set `zone: "not.a.zone"` on the widget. `bun run lint` (tsc) fails against `WidgetZoneId`.
228
+ 6. Delete the widget file. The prompt disappears. The seller route and hook are unaffected.
226
229
 
227
230
  ## FAQ
228
231
 
229
232
  <AccordionGroup>
230
233
  <Accordion title="Why additional_data instead of adding a body field?">
231
- The seller routes' validators are core-owned. `additional_data` is the sanctioned escape hatch every vendor and admin route wraps its body with `WithAdditionalData`, so you carry extra context to the workflow hooks without patching the request schema or forking the route.
234
+ The seller routes' validators are core-owned. `additional_data` is the sanctioned escape hatch. Every vendor and admin route wraps its body with `WithAdditionalData`, so you carry extra context to the workflow hooks without patching the request schema or forking the route.
232
235
  </Accordion>
233
236
  <Accordion title="Which seller workflows expose hooks?">
234
- `updateSellersWorkflow` exposes `sellersUpdated`, and `createSellerAccountWorkflow` (the `POST /vendor/sellers` onboarding submit) exposes `sellerAccountCreated` both carry `{ additional_data }`. Use `sellerAccountCreated` to capture data at first registration and `sellersUpdated` for later edits. See the [workflow references](/rc/references/workflows/seller/update-sellers).
237
+ `updateSellersWorkflow` exposes `sellersUpdated`, and `createSellerAccountWorkflow` (the `POST /vendor/sellers` onboarding submit) exposes `sellerAccountCreated`. Both carry `{ additional_data }`. Use `sellerAccountCreated` to capture data at first registration and `sellersUpdated` for later edits. See the [Store workflows](/platform/store/reference/workflows).
235
238
  </Accordion>
236
239
  <Accordion title="Can I store it on the seller's metadata instead?">
237
- Yes for a quick, non-queryable value, resolve the seller module in the hook and write to `seller.metadata`. Reach for the [Custom Fields module](/rc/resources/customization/custom-fields) when you want a typed, queryable column, which is what most onboarding data (tax IDs, compliance flags) needs.
240
+ Yes. For a quick, non-queryable value, resolve the seller module in the hook and write to `seller.metadata`. Reach for the [Custom Fields module](/rc/resources/customization/custom-fields) when you want a typed, queryable column, which is what most onboarding data such as tax IDs or compliance flags needs.
238
241
  </Accordion>
239
242
  <Accordion title="Does the hook run inside the request?">
240
- Yes workflow hooks run as steps of the workflow the route invokes, with the same compensation/rollback semantics. If your hook throws, the seller update rolls back. Keep slow or best-effort work (external syncs) in a subscriber on the emitted `seller.updated` event instead.
243
+ Yes. Workflow hooks run as steps of the workflow the route invokes, with the same compensation and rollback semantics. If your hook throws, the seller update rolls back. Keep slow or best-effort work, such as external syncs, in a subscriber on the emitted `seller.updated` event instead.
241
244
  </Accordion>
242
245
  </AccordionGroup>
243
246
 
@@ -245,7 +248,7 @@ seller.custom_fields.tax_id (durable, queryable)
245
248
 
246
249
  <CardGroup cols={2}>
247
250
  <Card title="Extend a workflow" href="/rc/resources/customization/extend-a-workflow">
248
- The full hook + compensation model for Mercur workflows.
251
+ The full hook and compensation model for Mercur workflows.
249
252
  </Card>
250
253
  <Card title="Custom Fields module" href="/rc/resources/customization/custom-fields">
251
254
  Durable, queryable storage for the data your hook writes.
@@ -1,20 +1,23 @@
1
1
  ---
2
- title: "Work with master products and offers"
3
- description: "Two sellers compete on one catalog entry: publish a master product, create competing offers, and read per-offer prices from the Store API."
2
+ title: "How to Create Master Products and Offers"
3
+ sidebarTitle: "Master Products & Offers"
4
+ description: "Publish one master product, add two competing seller offers, and read per-offer prices from the Store API."
4
5
  ---
5
6
 
6
- Mercur's catalog is a **master catalog**: one canonical product record, many sellers listing against it. The product defines *what the item is*; each seller's **offer** defines *how they sell it* their SKU, price, stock, and shipping. This tutorial builds the classic "buy box" scenario: two sellers, one product, two competing offers.
7
+ Mercur runs a master catalog. One canonical product record holds many sellers listing against it. The product defines what the item is. Each seller's offer defines how they sell it: their SKU, price, stock, and shipping. This tutorial builds the classic buy-box scenario: two sellers, one product, two competing offers.
7
8
 
8
9
  <Info>
9
- **No seller owns a product.** There is no owner column. Creating a product adds a candidate to the shared catalog the creator gets attribution (so their unpublished submissions appear in their own list) but no rights over the record after publication. What looks like ownership elsewhere is split into selling eligibility, creator attribution, and the status lifecycle. See [Products](/rc/learn/products).
10
+ No seller owns a product. There is no owner column. Creating a product adds a candidate to the shared catalog. The creator gets attribution, so their unpublished submissions appear in their own list, but no rights over the record after publication. What looks like ownership elsewhere is split into three things: selling eligibility, creator attribution, and the status lifecycle. See [Products](/rc/learn/products).
10
11
  </Info>
11
12
 
12
13
  ## What you'll build
13
14
 
14
- A published master product with offers from two sellers at different prices, visible side by side through the Store API with per-offer calculated prices.
15
+ You end with a published master product carrying offers from two sellers at different prices. Both offers are visible side by side through the Store API, each with its own calculated price.
15
16
 
16
17
  ## Product vs offer
17
18
 
19
+ Three concerns live in three places. Keep them separate as you build.
20
+
18
21
  | Concern | Lives on | Example |
19
22
  |---------|----------|---------|
20
23
  | What the item is | Master product | "Classic White T-Shirt", variants, attributes |
@@ -25,55 +28,57 @@ A published master product with offers from two sellers at different prices, vis
25
28
 
26
29
  <Steps>
27
30
  <Step title="Publish a master product">
28
- As Seller A, create a product in the Vendor Portal say "Classic White T-Shirt" with a size variant. It enters as `proposed`; as the operator, confirm it in the Admin Panel so it's `published` (the review flow is covered in [Handle product requests](/rc/resources/tutorials/handle-product-requests)).
31
+ As Seller A, create a product in the Vendor Portal, such as "Classic White T-Shirt" with a size variant. It enters as `proposed`. As the operator, confirm it in the Admin Panel so it becomes `published`. The review flow is covered by the [Product Edit](/platform/product-edit/overview) module.
29
32
 
30
- The published product now belongs to the shared catalog. Note what it does **not** have: a seller price or seller stock.
33
+ The published product now belongs to the shared catalog. Note what it does not have: a seller price or seller stock.
31
34
  </Step>
32
- <Step title="Seller A creates an offer">
33
- In Seller A's Vendor Portal, create an offer against the product's variant: their own SKU, a price of $25, stock of 100, and one of their shipping profiles.
35
+ <Step title="Create Seller A's offer">
36
+ In Seller A's Vendor Portal, create an offer against the product's variant. Give it their own SKU, a price of $25, stock of 100, and one of their shipping profiles.
34
37
 
35
38
  <Warning>
36
- Offer inventory is linked to the **offer, not the variant**. Each seller manages stock for their own listing independently a variant has no marketplace-wide stock figure, and its own `inventory_items` relation is empty for offer-based listings. Always read stock through the offer.
39
+ Offer inventory links to the offer, not the variant. Each seller manages stock for their own listing independently. A variant has no marketplace-wide stock figure, and its own `inventory_items` relation is empty for offer-based listings. Always read stock through the offer.
37
40
  </Warning>
38
41
  </Step>
39
- <Step title="Seller B lists the same product">
40
- As Seller B, find the same published product in the catalog and create a competing offer on the same variant different SKU, $23, stock of 40. The `(seller_id, sku)` pair is unique per seller, so both sellers can use whatever SKU scheme they like.
42
+ <Step title="List the same product as Seller B">
43
+ As Seller B, find the same published product in the catalog and create a competing offer on the same variant: a different SKU, $23, stock of 40. The `(seller_id, sku)` pair is unique per seller, so both sellers can use whatever SKU scheme they like.
41
44
 
42
45
  Nothing about the master product changed. Two commercial listings now point at one catalog entry.
43
46
  </Step>
44
47
  <Step title="Read the buy box from the Store API">
45
- The Store API exposes offers directly, each with its own calculated price:
48
+ The Store API exposes offers directly, each with its own calculated price. Fetch them by product id:
46
49
 
47
- ```bash
50
+ ```bash Terminal
48
51
  curl "http://localhost:9000/store/offers?product_id=prod_123" \
49
52
  -H "x-publishable-api-key: <key>"
50
53
  ```
51
54
 
52
- Offers share the variant's price set scoped by an offer rule each offer carries its own prices without duplicating the variant, and the storefront computes a `calculated_price` per offer. A buy-box storefront fetches the product once, then renders every seller's offer against it.
55
+ Offers share the variant's price set scoped by an offer rule. Each offer carries its own prices without duplicating the variant, and the storefront computes a `calculated_price` per offer. A buy-box storefront fetches the product once, then renders every seller's offer against it.
53
56
  </Step>
54
57
  <Step title="Check out against an offer">
55
- Add Seller B's offer to a cart and place the order. The cart line item links to the **specific offer** purchased, and that link is preserved onto the order line item — so fulfillment, [commission calculation](/rc/learn/commissions), and [payouts](/rc/learn/payouts) all resolve to Seller B, even though both sellers list the same variant.
58
+ Add Seller B's offer to a cart and place the order. The cart line item links to the specific offer purchased, and that link is preserved onto the order line item. Fulfillment, [commission calculation](/rc/learn/commissions), and [payouts](/rc/learn/payouts) all resolve to Seller B, even though both sellers list the same variant.
56
59
  </Step>
57
60
  </Steps>
58
61
 
59
62
  ## Verify
60
63
 
64
+ Confirm the buy box behaves as expected.
65
+
61
66
  1. Both offers appear in `GET /store/offers?product_id=...` with different `calculated_price` values.
62
- 2. Each seller's Vendor Portal shows only their own offer; the Admin Panel lists both with store, pricing, and inventory.
63
- 3. After the checkout in step 5, the order lands with Seller B; Seller A's offer and stock are untouched.
64
- 4. Reducing Seller B's offer stock doesn't affect Seller A's availability inventory is per offer.
67
+ 2. Each seller's Vendor Portal shows only their own offer. The Admin Panel lists both with store, pricing, and inventory.
68
+ 3. After the checkout in step 5, the order lands with Seller B. Seller A's offer and stock are untouched.
69
+ 4. Reducing Seller B's offer stock does not affect Seller A's availability. Inventory is per offer.
65
70
 
66
71
  ## FAQ
67
72
 
68
73
  <AccordionGroup>
69
74
  <Accordion title="How do I restrict who may sell a product?">
70
- The operator manages the `product_seller` allowlist: a product with assignments is visible and sellable only for those sellers, while a product with **no** assignments is open to every seller. Eligibility limits selling it does not limit who may propose edits to the shared record.
75
+ The operator manages the `product_seller` allowlist. A product with assignments is visible and sellable only for those sellers, while a product with no assignments is open to every seller. Eligibility limits selling. It does not limit who may propose edits to the shared record.
71
76
  </Accordion>
72
77
  <Accordion title="Can two sellers use the same SKU?">
73
- Yes SKU uniqueness is per seller (`seller_id` + `sku`). Seller A and Seller B can both use `TSHIRT-WHITE-M`; a single seller cannot list the same SKU twice.
78
+ Yes. SKU uniqueness is per seller (`seller_id` + `sku`). Seller A and Seller B can both use `TSHIRT-WHITE-M`. A single seller cannot list the same SKU twice.
74
79
  </Accordion>
75
80
  <Accordion title="Who fulfills, refunds, and gets paid when several sellers list the same variant?">
76
- Always the seller whose **offer** was purchased. The offer link travels from cart line to order line, so fulfillment, returns, commission, and payout all resolve through it the variant alone is never enough to identify the seller.
81
+ Always the seller whose offer was purchased. The offer link travels from cart line to order line, so fulfillment, returns, commission, and payout all resolve through it. The variant alone is never enough to identify the seller.
77
82
  </Accordion>
78
83
  </AccordionGroup>
79
84
 
@@ -84,6 +89,6 @@ A published master product with offers from two sellers at different prices, vis
84
89
  The offer data model, relationships, and checkout links.
85
90
  </Card>
86
91
  <Card title="Order Groups" href="/rc/learn/order-groups">
87
- What happens when a cart spans both sellers the multi-vendor split.
92
+ What happens when a cart spans both sellers: the multi-vendor split.
88
93
  </Card>
89
94
  </CardGroup>
@@ -39,7 +39,7 @@ When you run CLI commands (`create`, `init`, `add`, `registry:build`), the follo
39
39
  ### Using the CLI
40
40
 
41
41
  ```bash
42
- mercurjs telemetry --disable
42
+ bunx @mercurjs/cli@latest telemetry --disable
43
43
  ```
44
44
 
45
45
  ### Using an environment variable
@@ -53,7 +53,7 @@ This is useful for CI/CD environments or shared configurations.
53
53
  ### Check current status
54
54
 
55
55
  ```bash
56
- mercurjs telemetry
56
+ bunx @mercurjs/cli@latest telemetry
57
57
  ```
58
58
 
59
59
  ## Where Data Goes
@@ -63,5 +63,5 @@ Telemetry events are sent to `https://telemetry.mercurjs.com`. The data is used
63
63
  ## Re-enabling Telemetry
64
64
 
65
65
  ```bash
66
- mercurjs telemetry --enable
66
+ bunx @mercurjs/cli@latest telemetry --enable
67
67
  ```