@vendure/docs 0.0.0-202601161541

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 (968) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +2 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/manifest.d.ts +3 -0
  6. package/dist/manifest.d.ts.map +1 -0
  7. package/dist/manifest.js +857 -0
  8. package/dist/manifest.js.map +1 -0
  9. package/docs/guides/core-concepts/auth/admin-role.webp +0 -0
  10. package/docs/guides/core-concepts/auth/admin.webp +0 -0
  11. package/docs/guides/core-concepts/auth/customer.webp +0 -0
  12. package/docs/guides/core-concepts/auth/index.md +557 -0
  13. package/docs/guides/core-concepts/auth/roles.webp +0 -0
  14. package/docs/guides/core-concepts/channels/channel-token.webp +0 -0
  15. package/docs/guides/core-concepts/channels/channels.webp +0 -0
  16. package/docs/guides/core-concepts/channels/channels_currencies_diagram.png +0 -0
  17. package/docs/guides/core-concepts/channels/channels_diagram.png +0 -0
  18. package/docs/guides/core-concepts/channels/channels_prices_diagram.png +0 -0
  19. package/docs/guides/core-concepts/channels/default-currency.webp +0 -0
  20. package/docs/guides/core-concepts/channels/index.md +154 -0
  21. package/docs/guides/core-concepts/channels/variant-prices.webp +0 -0
  22. package/docs/guides/core-concepts/collections/collection-filters.webp +0 -0
  23. package/docs/guides/core-concepts/collections/collections.webp +0 -0
  24. package/docs/guides/core-concepts/collections/filter-inheritance.webp +0 -0
  25. package/docs/guides/core-concepts/collections/index.mdx +125 -0
  26. package/docs/guides/core-concepts/customers/customer.webp +0 -0
  27. package/docs/guides/core-concepts/customers/index.mdx +21 -0
  28. package/docs/guides/core-concepts/email/email-plugin-flow.webp +0 -0
  29. package/docs/guides/core-concepts/email/index.mdx +155 -0
  30. package/docs/guides/core-concepts/images-assets/asset-flow.webp +0 -0
  31. package/docs/guides/core-concepts/images-assets/asset-tags.webp +0 -0
  32. package/docs/guides/core-concepts/images-assets/index.mdx +42 -0
  33. package/docs/guides/core-concepts/money/index.mdx +246 -0
  34. package/docs/guides/core-concepts/orders/custom-order-ui.webp +0 -0
  35. package/docs/guides/core-concepts/orders/index.md +366 -0
  36. package/docs/guides/core-concepts/orders/order-process.webp +0 -0
  37. package/docs/guides/core-concepts/orders/order.webp +0 -0
  38. package/docs/guides/core-concepts/payment/index.md +410 -0
  39. package/docs/guides/core-concepts/payment/payment-method.webp +0 -0
  40. package/docs/guides/core-concepts/payment/payment_sequence_one_step.png +0 -0
  41. package/docs/guides/core-concepts/payment/payment_sequence_two_step.png +0 -0
  42. package/docs/guides/core-concepts/products/facets.webp +0 -0
  43. package/docs/guides/core-concepts/products/index.mdx +59 -0
  44. package/docs/guides/core-concepts/products/product-relations.webp +0 -0
  45. package/docs/guides/core-concepts/products/products-variants.webp +0 -0
  46. package/docs/guides/core-concepts/promotions/index.md +324 -0
  47. package/docs/guides/core-concepts/shipping/index.md +225 -0
  48. package/docs/guides/core-concepts/shipping/shipping-method.webp +0 -0
  49. package/docs/guides/core-concepts/stock-control/global-stock-control.webp +0 -0
  50. package/docs/guides/core-concepts/stock-control/index.md +233 -0
  51. package/docs/guides/core-concepts/stock-control/stock-levels.webp +0 -0
  52. package/docs/guides/core-concepts/taxes/index.mdx +76 -0
  53. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/01-create-space.webp +0 -0
  54. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/02-space-access-keys.webp +0 -0
  55. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/03-create-app.webp +0 -0
  56. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/04-configure-server.webp +0 -0
  57. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/05-open-server-settings.webp +0 -0
  58. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/06-admin-app-route.webp +0 -0
  59. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/07-open-app.webp +0 -0
  60. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/deploy-to-do-app-platform.webp +0 -0
  61. package/docs/guides/deployment/deploy-to-digital-ocean-app-platform/index.md +246 -0
  62. package/docs/guides/deployment/deploy-to-google-cloud-run/deploy-to-gcr.webp +0 -0
  63. package/docs/guides/deployment/deploy-to-google-cloud-run/index.md +53 -0
  64. package/docs/guides/deployment/deploy-to-northflank/01-create-template-screen.webp +0 -0
  65. package/docs/guides/deployment/deploy-to-northflank/02-paste-config.webp +0 -0
  66. package/docs/guides/deployment/deploy-to-northflank/03-run-template.webp +0 -0
  67. package/docs/guides/deployment/deploy-to-northflank/04-find-project.webp +0 -0
  68. package/docs/guides/deployment/deploy-to-northflank/05-server-service.webp +0 -0
  69. package/docs/guides/deployment/deploy-to-northflank/06-find-url.webp +0 -0
  70. package/docs/guides/deployment/deploy-to-northflank/deploy-to-northflank.webp +0 -0
  71. package/docs/guides/deployment/deploy-to-northflank/index.md +606 -0
  72. package/docs/guides/deployment/deploy-to-railway/01-new-service.webp +0 -0
  73. package/docs/guides/deployment/deploy-to-railway/02-env-vars.webp +0 -0
  74. package/docs/guides/deployment/deploy-to-railway/03-test-server.webp +0 -0
  75. package/docs/guides/deployment/deploy-to-railway/deploy-to-railway.webp +0 -0
  76. package/docs/guides/deployment/deploy-to-railway/index.md +202 -0
  77. package/docs/guides/deployment/deploy-to-render/01-create-db.webp +0 -0
  78. package/docs/guides/deployment/deploy-to-render/02-env-group.webp +0 -0
  79. package/docs/guides/deployment/deploy-to-render/03-db-connection.webp +0 -0
  80. package/docs/guides/deployment/deploy-to-render/04-link-env-group.webp +0 -0
  81. package/docs/guides/deployment/deploy-to-render/05-server-url.webp +0 -0
  82. package/docs/guides/deployment/deploy-to-render/deploy-to-render.webp +0 -0
  83. package/docs/guides/deployment/deploy-to-render/index.md +221 -0
  84. package/docs/guides/deployment/deploying-admin-ui.md +130 -0
  85. package/docs/guides/deployment/getting-data-into-production.md +50 -0
  86. package/docs/guides/deployment/horizontal-scaling.md +75 -0
  87. package/docs/guides/deployment/production-configuration/env-var-ui.webp +0 -0
  88. package/docs/guides/deployment/production-configuration/index.md +140 -0
  89. package/docs/guides/deployment/server-resource-requirements.md +29 -0
  90. package/docs/guides/deployment/using-docker.md +193 -0
  91. package/docs/guides/developer-guide/cache/cache-service.webp +0 -0
  92. package/docs/guides/developer-guide/cache/index.mdx +327 -0
  93. package/docs/guides/developer-guide/channel-aware/index.md +117 -0
  94. package/docs/guides/developer-guide/cli/add-command.webp +0 -0
  95. package/docs/guides/developer-guide/cli/index.md +418 -0
  96. package/docs/guides/developer-guide/cli/migrate-command.webp +0 -0
  97. package/docs/guides/developer-guide/cli/schema-command.webp +0 -0
  98. package/docs/guides/developer-guide/configuration/index.md +226 -0
  99. package/docs/guides/developer-guide/custom-fields/custom-fields-data-table.webp +0 -0
  100. package/docs/guides/developer-guide/custom-fields/custom-fields-ui.webp +0 -0
  101. package/docs/guides/developer-guide/custom-fields/index.md +1423 -0
  102. package/docs/guides/developer-guide/custom-permissions/index.md +186 -0
  103. package/docs/guides/developer-guide/custom-strategies-in-plugins/index.mdx +467 -0
  104. package/docs/guides/developer-guide/database-entity/index.md +136 -0
  105. package/docs/guides/developer-guide/dataloaders/index.md +137 -0
  106. package/docs/guides/developer-guide/db-subscribers/index.md +115 -0
  107. package/docs/guides/developer-guide/error-handling/index.mdx +324 -0
  108. package/docs/guides/developer-guide/events/index.mdx +406 -0
  109. package/docs/guides/developer-guide/extend-graphql-api/index.md +501 -0
  110. package/docs/guides/developer-guide/has-custom-fields/index.md +174 -0
  111. package/docs/guides/developer-guide/importing-data/index.md +488 -0
  112. package/docs/guides/developer-guide/importing-data/reindex.webp +0 -0
  113. package/docs/guides/developer-guide/logging/index.md +77 -0
  114. package/docs/guides/developer-guide/migrating-from-v1/breaking-api-changes.md +213 -0
  115. package/docs/guides/developer-guide/migrating-from-v1/database-migration.md +39 -0
  116. package/docs/guides/developer-guide/migrating-from-v1/index.md +41 -0
  117. package/docs/guides/developer-guide/migrating-from-v1/storefront-migration.md +30 -0
  118. package/docs/guides/developer-guide/migrations/index.md +197 -0
  119. package/docs/guides/developer-guide/migrations/migration.webp +0 -0
  120. package/docs/guides/developer-guide/nest-devtools/index.md +74 -0
  121. package/docs/guides/developer-guide/nest-devtools/nest-devtools-bootstrap-perf.webp +0 -0
  122. package/docs/guides/developer-guide/nest-devtools/nest-devtools-graph.webp +0 -0
  123. package/docs/guides/developer-guide/overview/Vendure_docs-architecture.webp +0 -0
  124. package/docs/guides/developer-guide/overview/index.md +40 -0
  125. package/docs/guides/developer-guide/plugins/index.mdx +806 -0
  126. package/docs/guides/developer-guide/rest-endpoint/index.md +99 -0
  127. package/docs/guides/developer-guide/scheduled-tasks/index.md +298 -0
  128. package/docs/guides/developer-guide/security/index.md +264 -0
  129. package/docs/guides/developer-guide/settings-store/index.mdx +553 -0
  130. package/docs/guides/developer-guide/stand-alone-scripts/index.md +119 -0
  131. package/docs/guides/developer-guide/strategies-configurable-operations/collection-filters-args.webp +0 -0
  132. package/docs/guides/developer-guide/strategies-configurable-operations/collection-filters.webp +0 -0
  133. package/docs/guides/developer-guide/strategies-configurable-operations/index.mdx +373 -0
  134. package/docs/guides/developer-guide/testing/index.md +254 -0
  135. package/docs/guides/developer-guide/the-api-layer/Vendure_docs-api_request.webp +0 -0
  136. package/docs/guides/developer-guide/the-api-layer/index.mdx +474 -0
  137. package/docs/guides/developer-guide/the-service-layer/index.mdx +311 -0
  138. package/docs/guides/developer-guide/translatable/index.md +224 -0
  139. package/docs/guides/developer-guide/translations/index.md +165 -0
  140. package/docs/guides/developer-guide/updating/index.md +79 -0
  141. package/docs/guides/developer-guide/uploading-files/index.md +220 -0
  142. package/docs/guides/developer-guide/worker-job-queue/Vendure_docs-job-queue-2.webp +0 -0
  143. package/docs/guides/developer-guide/worker-job-queue/Vendure_docs-job-queue-3.webp +0 -0
  144. package/docs/guides/developer-guide/worker-job-queue/Vendure_docs-job-queue.webp +0 -0
  145. package/docs/guides/developer-guide/worker-job-queue/index.mdx +522 -0
  146. package/docs/guides/developer-guide/worker-job-queue/worker-job-queue.webp +0 -0
  147. package/docs/guides/extending-the-admin-ui/add-actions-to-pages/index.md +233 -0
  148. package/docs/guides/extending-the-admin-ui/add-actions-to-pages/ui-extensions-actionbar-dropdown.webp +0 -0
  149. package/docs/guides/extending-the-admin-ui/add-actions-to-pages/ui-extensions-actionbar.webp +0 -0
  150. package/docs/guides/extending-the-admin-ui/adding-ui-translations/index.md +113 -0
  151. package/docs/guides/extending-the-admin-ui/adding-ui-translations/ui-translations-01.webp +0 -0
  152. package/docs/guides/extending-the-admin-ui/admin-ui-theming-branding/index.md +133 -0
  153. package/docs/guides/extending-the-admin-ui/alerts/alerts-01.webp +0 -0
  154. package/docs/guides/extending-the-admin-ui/alerts/index.md +56 -0
  155. package/docs/guides/extending-the-admin-ui/bulk-actions/bulk-actions-screenshot.webp +0 -0
  156. package/docs/guides/extending-the-admin-ui/bulk-actions/index.md +78 -0
  157. package/docs/guides/extending-the-admin-ui/creating-detail-views/index.md +332 -0
  158. package/docs/guides/extending-the-admin-ui/creating-list-views/index.md +331 -0
  159. package/docs/guides/extending-the-admin-ui/custom-data-table-components/custom-data-table-location.webp +0 -0
  160. package/docs/guides/extending-the-admin-ui/custom-data-table-components/custom-data-table.webp +0 -0
  161. package/docs/guides/extending-the-admin-ui/custom-data-table-components/index.md +111 -0
  162. package/docs/guides/extending-the-admin-ui/custom-detail-components/detail-component.webp +0 -0
  163. package/docs/guides/extending-the-admin-ui/custom-detail-components/index.md +198 -0
  164. package/docs/guides/extending-the-admin-ui/custom-form-inputs/index.md +285 -0
  165. package/docs/guides/extending-the-admin-ui/custom-form-inputs/ui-extensions-custom-field-default.webp +0 -0
  166. package/docs/guides/extending-the-admin-ui/custom-form-inputs/ui-extensions-custom-field-slider.webp +0 -0
  167. package/docs/guides/extending-the-admin-ui/custom-timeline-components/index.md +79 -0
  168. package/docs/guides/extending-the-admin-ui/custom-timeline-components/timeline-entry.webp +0 -0
  169. package/docs/guides/extending-the-admin-ui/dashboard-widgets/dashboard-widgets.webp +0 -0
  170. package/docs/guides/extending-the-admin-ui/dashboard-widgets/index.md +149 -0
  171. package/docs/guides/extending-the-admin-ui/defining-routes/index.md +777 -0
  172. package/docs/guides/extending-the-admin-ui/defining-routes/route-area.webp +0 -0
  173. package/docs/guides/extending-the-admin-ui/defining-routes/ui-extensions-greeter.webp +0 -0
  174. package/docs/guides/extending-the-admin-ui/getting-started/index.md +656 -0
  175. package/docs/guides/extending-the-admin-ui/getting-started/provider-extension-points.webp +0 -0
  176. package/docs/guides/extending-the-admin-ui/nav-menu/index.md +97 -0
  177. package/docs/guides/extending-the-admin-ui/nav-menu/nav-menu-id.webp +0 -0
  178. package/docs/guides/extending-the-admin-ui/nav-menu/ui-extensions-navbar.webp +0 -0
  179. package/docs/guides/extending-the-admin-ui/page-tabs/index.md +44 -0
  180. package/docs/guides/extending-the-admin-ui/page-tabs/ui-extensions-tabs.webp +0 -0
  181. package/docs/guides/extending-the-admin-ui/ui-library/buttons.webp +0 -0
  182. package/docs/guides/extending-the-admin-ui/ui-library/card.webp +0 -0
  183. package/docs/guides/extending-the-admin-ui/ui-library/form-inputs.webp +0 -0
  184. package/docs/guides/extending-the-admin-ui/ui-library/icons.webp +0 -0
  185. package/docs/guides/extending-the-admin-ui/ui-library/index.md +356 -0
  186. package/docs/guides/extending-the-admin-ui/ui-library/layout.webp +0 -0
  187. package/docs/guides/extending-the-admin-ui/using-other-frameworks/index.md +205 -0
  188. package/docs/guides/extending-the-admin-ui/using-other-frameworks/ui-extensions-cra.jpg +0 -0
  189. package/docs/guides/extending-the-dashboard/alerts/alert.webp +0 -0
  190. package/docs/guides/extending-the-dashboard/alerts/index.md +89 -0
  191. package/docs/guides/extending-the-dashboard/creating-pages/detail-pages.md +316 -0
  192. package/docs/guides/extending-the-dashboard/creating-pages/index.md +90 -0
  193. package/docs/guides/extending-the-dashboard/creating-pages/list-pages.md +206 -0
  194. package/docs/guides/extending-the-dashboard/creating-pages/tabbed-page-example.webp +0 -0
  195. package/docs/guides/extending-the-dashboard/creating-pages/tabbed-pages.md +144 -0
  196. package/docs/guides/extending-the-dashboard/custom-form-components/color-picker.webp +0 -0
  197. package/docs/guides/extending-the-dashboard/custom-form-components/dev-mode.webp +0 -0
  198. package/docs/guides/extending-the-dashboard/custom-form-components/example-currency-input.webp +0 -0
  199. package/docs/guides/extending-the-dashboard/custom-form-components/example-email-input.webp +0 -0
  200. package/docs/guides/extending-the-dashboard/custom-form-components/example-slug-input.webp +0 -0
  201. package/docs/guides/extending-the-dashboard/custom-form-components/example-tags-input.webp +0 -0
  202. package/docs/guides/extending-the-dashboard/custom-form-components/form-component-examples.mdx +445 -0
  203. package/docs/guides/extending-the-dashboard/custom-form-components/index.md +465 -0
  204. package/docs/guides/extending-the-dashboard/custom-form-components/locator.webp +0 -0
  205. package/docs/guides/extending-the-dashboard/custom-form-components/relation-selectors.md +687 -0
  206. package/docs/guides/extending-the-dashboard/customizing-pages/action-bar-button.webp +0 -0
  207. package/docs/guides/extending-the-dashboard/customizing-pages/action-bar-dropdown.webp +0 -0
  208. package/docs/guides/extending-the-dashboard/customizing-pages/action-bar-items.md +272 -0
  209. package/docs/guides/extending-the-dashboard/customizing-pages/custom-widget.webp +0 -0
  210. package/docs/guides/extending-the-dashboard/customizing-pages/customizing-detail-pages.md +129 -0
  211. package/docs/guides/extending-the-dashboard/customizing-pages/customizing-list-pages.md +93 -0
  212. package/docs/guides/extending-the-dashboard/customizing-pages/customizing-login-page.md +66 -0
  213. package/docs/guides/extending-the-dashboard/customizing-pages/history-entries.md +43 -0
  214. package/docs/guides/extending-the-dashboard/customizing-pages/history-entry.webp +0 -0
  215. package/docs/guides/extending-the-dashboard/customizing-pages/index.md +10 -0
  216. package/docs/guides/extending-the-dashboard/customizing-pages/insights-widgets.md +57 -0
  217. package/docs/guides/extending-the-dashboard/customizing-pages/login-page.webp +0 -0
  218. package/docs/guides/extending-the-dashboard/customizing-pages/page-blocks.md +244 -0
  219. package/docs/guides/extending-the-dashboard/data-fetching/index.md +126 -0
  220. package/docs/guides/extending-the-dashboard/data-fetching/type-inference.webp +0 -0
  221. package/docs/guides/extending-the-dashboard/deployment/index.md +200 -0
  222. package/docs/guides/extending-the-dashboard/extending-overview/dev-mode.webp +0 -0
  223. package/docs/guides/extending-the-dashboard/extending-overview/index.md +228 -0
  224. package/docs/guides/extending-the-dashboard/extending-overview/location-id.webp +0 -0
  225. package/docs/guides/extending-the-dashboard/getting-started/detail-view.webp +0 -0
  226. package/docs/guides/extending-the-dashboard/getting-started/index.md +194 -0
  227. package/docs/guides/extending-the-dashboard/getting-started/list-view-empty.webp +0 -0
  228. package/docs/guides/extending-the-dashboard/getting-started/list-view-full.webp +0 -0
  229. package/docs/guides/extending-the-dashboard/getting-started/page-block.webp +0 -0
  230. package/docs/guides/extending-the-dashboard/getting-started/test-page.webp +0 -0
  231. package/docs/guides/extending-the-dashboard/localization/index.md +94 -0
  232. package/docs/guides/extending-the-dashboard/migration/index.md +1902 -0
  233. package/docs/guides/extending-the-dashboard/navigation/dev-mode-nav.webp +0 -0
  234. package/docs/guides/extending-the-dashboard/navigation/index.md +322 -0
  235. package/docs/guides/extending-the-dashboard/navigation/unauthenticated-page.webp +0 -0
  236. package/docs/guides/extending-the-dashboard/tech-stack/index.md +395 -0
  237. package/docs/guides/extending-the-dashboard/theming/index.md +180 -0
  238. package/docs/guides/extending-the-dashboard/theming/show-colour-value-inspection.gif +0 -0
  239. package/docs/guides/getting-started/graphql-intro/index.mdx +572 -0
  240. package/docs/guides/getting-started/installation/app-screens.webp +0 -0
  241. package/docs/guides/getting-started/installation/index.md +234 -0
  242. package/docs/guides/getting-started/try-the-api/graphiql-docs.jpeg +0 -0
  243. package/docs/guides/getting-started/try-the-api/graphiql.jpeg +0 -0
  244. package/docs/guides/getting-started/try-the-api/index.mdx +238 -0
  245. package/docs/guides/how-to/cms-integration-plugin/index.mdx +2083 -0
  246. package/docs/guides/how-to/codegen/index.md +280 -0
  247. package/docs/guides/how-to/configurable-products/index.md +138 -0
  248. package/docs/guides/how-to/digital-products/index.mdx +485 -0
  249. package/docs/guides/how-to/digital-products/product-variant.webp +0 -0
  250. package/docs/guides/how-to/digital-products/shipping-method.webp +0 -0
  251. package/docs/guides/how-to/github-oauth-authentication/index.mdx +360 -0
  252. package/docs/guides/how-to/google-oauth-authentication/index.mdx +494 -0
  253. package/docs/guides/how-to/multi-vendor-marketplaces/aggregate-order.webp +0 -0
  254. package/docs/guides/how-to/multi-vendor-marketplaces/index.md +197 -0
  255. package/docs/guides/how-to/paginated-list/index.mdx +360 -0
  256. package/docs/guides/how-to/publish-plugin/index.mdx +402 -0
  257. package/docs/guides/how-to/s3-asset-storage/index.mdx +572 -0
  258. package/docs/guides/how-to/telemetry/grafana-logs.webp +0 -0
  259. package/docs/guides/how-to/telemetry/grafana-trace.webp +0 -0
  260. package/docs/guides/how-to/telemetry/index.md +260 -0
  261. package/docs/guides/how-to/telemetry/jaeger-trace.webp +0 -0
  262. package/docs/guides/storefront/active-order/index.mdx +201 -0
  263. package/docs/guides/storefront/checkout-flow/index.mdx +428 -0
  264. package/docs/guides/storefront/codegen/index.mdx +157 -0
  265. package/docs/guides/storefront/connect-api/index.mdx +677 -0
  266. package/docs/guides/storefront/customer-accounts/index.mdx +389 -0
  267. package/docs/guides/storefront/customer-accounts/pw-reset.webp +0 -0
  268. package/docs/guides/storefront/customer-accounts/verification.webp +0 -0
  269. package/docs/guides/storefront/listing-products/index.mdx +711 -0
  270. package/docs/guides/storefront/navigation-menu/index.mdx +157 -0
  271. package/docs/guides/storefront/order-workflow/index.md +231 -0
  272. package/docs/guides/storefront/order-workflow/order_class_diagram.png +0 -0
  273. package/docs/guides/storefront/order-workflow/order_state_diagram.png +0 -0
  274. package/docs/guides/storefront/product-detail/index.mdx +295 -0
  275. package/docs/guides/storefront/storefront-starters/angular-storefront.webp +0 -0
  276. package/docs/guides/storefront/storefront-starters/index.mdx +69 -0
  277. package/docs/guides/storefront/storefront-starters/next-storefront.webp +0 -0
  278. package/docs/guides/storefront/storefront-starters/qwik-storefront.webp +0 -0
  279. package/docs/guides/storefront/storefront-starters/remix-storefront.webp +0 -0
  280. package/docs/reference/admin-ui-api/action-bar/action-bar-context.md +82 -0
  281. package/docs/reference/admin-ui-api/action-bar/action-bar-dropdown-menu-item.md +93 -0
  282. package/docs/reference/admin-ui-api/action-bar/action-bar-item.md +106 -0
  283. package/docs/reference/admin-ui-api/action-bar/action-bar-location-id.md +17 -0
  284. package/docs/reference/admin-ui-api/action-bar/add-action-bar-dropdown-menu-item.md +38 -0
  285. package/docs/reference/admin-ui-api/action-bar/add-action-bar-item.md +36 -0
  286. package/docs/reference/admin-ui-api/action-bar/index.md +5 -0
  287. package/docs/reference/admin-ui-api/action-bar/page-location-id.md +61 -0
  288. package/docs/reference/admin-ui-api/action-bar/router-link-definition.md +16 -0
  289. package/docs/reference/admin-ui-api/alerts/alert-config.md +88 -0
  290. package/docs/reference/admin-ui-api/alerts/alert-context.md +52 -0
  291. package/docs/reference/admin-ui-api/alerts/index.md +5 -0
  292. package/docs/reference/admin-ui-api/alerts/register-alert.md +23 -0
  293. package/docs/reference/admin-ui-api/bulk-actions/bulk-action.md +229 -0
  294. package/docs/reference/admin-ui-api/bulk-actions/index.md +5 -0
  295. package/docs/reference/admin-ui-api/bulk-actions/register-bulk-action.md +63 -0
  296. package/docs/reference/admin-ui-api/components/asset-picker-dialog-component.md +160 -0
  297. package/docs/reference/admin-ui-api/components/chip-component.md +63 -0
  298. package/docs/reference/admin-ui-api/components/currency-input-component.md +174 -0
  299. package/docs/reference/admin-ui-api/components/data-table-component.md +238 -0
  300. package/docs/reference/admin-ui-api/components/data-table2component.md +354 -0
  301. package/docs/reference/admin-ui-api/components/datetime-picker-component.md +262 -0
  302. package/docs/reference/admin-ui-api/components/dropdown-component.md +86 -0
  303. package/docs/reference/admin-ui-api/components/facet-value-selector-component.md +155 -0
  304. package/docs/reference/admin-ui-api/components/index.md +5 -0
  305. package/docs/reference/admin-ui-api/components/object-tree-component.md +86 -0
  306. package/docs/reference/admin-ui-api/components/order-state-label-component.md +41 -0
  307. package/docs/reference/admin-ui-api/components/product-variant-selector-component.md +75 -0
  308. package/docs/reference/admin-ui-api/components/rich-text-editor-component.md +108 -0
  309. package/docs/reference/admin-ui-api/components/zone-selector-component.md +124 -0
  310. package/docs/reference/admin-ui-api/custom-detail-components/custom-detail-component-config.md +41 -0
  311. package/docs/reference/admin-ui-api/custom-detail-components/custom-detail-component-location-id.md +36 -0
  312. package/docs/reference/admin-ui-api/custom-detail-components/custom-detail-component.md +36 -0
  313. package/docs/reference/admin-ui-api/custom-detail-components/index.md +5 -0
  314. package/docs/reference/admin-ui-api/custom-detail-components/register-custom-detail-component.md +69 -0
  315. package/docs/reference/admin-ui-api/custom-history-entry-components/customer-history-entry-component.md +32 -0
  316. package/docs/reference/admin-ui-api/custom-history-entry-components/history-entry-component.md +57 -0
  317. package/docs/reference/admin-ui-api/custom-history-entry-components/history-entry-config.md +35 -0
  318. package/docs/reference/admin-ui-api/custom-history-entry-components/index.md +5 -0
  319. package/docs/reference/admin-ui-api/custom-history-entry-components/order-history-entry-component.md +32 -0
  320. package/docs/reference/admin-ui-api/custom-history-entry-components/register-history-entry-component.md +79 -0
  321. package/docs/reference/admin-ui-api/custom-input-components/default-inputs.md +1034 -0
  322. package/docs/reference/admin-ui-api/custom-input-components/form-input-component.md +56 -0
  323. package/docs/reference/admin-ui-api/custom-input-components/index.md +5 -0
  324. package/docs/reference/admin-ui-api/custom-input-components/register-form-input-component.md +71 -0
  325. package/docs/reference/admin-ui-api/custom-table-components/custom-column-component.md +32 -0
  326. package/docs/reference/admin-ui-api/custom-table-components/data-table-component-config.md +48 -0
  327. package/docs/reference/admin-ui-api/custom-table-components/index.md +5 -0
  328. package/docs/reference/admin-ui-api/custom-table-components/register-data-table-component.md +55 -0
  329. package/docs/reference/admin-ui-api/dashboard-widgets/dashboard-widget-config.md +60 -0
  330. package/docs/reference/admin-ui-api/dashboard-widgets/index.md +5 -0
  331. package/docs/reference/admin-ui-api/dashboard-widgets/register-dashboard-widget.md +27 -0
  332. package/docs/reference/admin-ui-api/dashboard-widgets/set-dashboard-widget-layout.md +22 -0
  333. package/docs/reference/admin-ui-api/dashboard-widgets/widget-layout-definition.md +16 -0
  334. package/docs/reference/admin-ui-api/directives/if-multichannel-directive.md +41 -0
  335. package/docs/reference/admin-ui-api/directives/if-permissions-directive.md +43 -0
  336. package/docs/reference/admin-ui-api/directives/index.md +5 -0
  337. package/docs/reference/admin-ui-api/index.md +13 -0
  338. package/docs/reference/admin-ui-api/list-detail-views/base-detail-component.md +168 -0
  339. package/docs/reference/admin-ui-api/list-detail-views/base-entity-resolver.md +54 -0
  340. package/docs/reference/admin-ui-api/list-detail-views/base-list-component.md +155 -0
  341. package/docs/reference/admin-ui-api/list-detail-views/detail-component-with-resolver.md +52 -0
  342. package/docs/reference/admin-ui-api/list-detail-views/index.md +5 -0
  343. package/docs/reference/admin-ui-api/list-detail-views/typed-base-detail-component.md +51 -0
  344. package/docs/reference/admin-ui-api/list-detail-views/typed-base-list-component.md +125 -0
  345. package/docs/reference/admin-ui-api/nav-menu/add-nav-menu-item.md +52 -0
  346. package/docs/reference/admin-ui-api/nav-menu/add-nav-menu-section.md +47 -0
  347. package/docs/reference/admin-ui-api/nav-menu/index.md +5 -0
  348. package/docs/reference/admin-ui-api/nav-menu/nav-menu-item.md +66 -0
  349. package/docs/reference/admin-ui-api/nav-menu/nav-menu-section.md +83 -0
  350. package/docs/reference/admin-ui-api/nav-menu/navigation-types.md +38 -0
  351. package/docs/reference/admin-ui-api/pipes/asset-preview-pipe.md +41 -0
  352. package/docs/reference/admin-ui-api/pipes/duration-pipe.md +45 -0
  353. package/docs/reference/admin-ui-api/pipes/file-size-pipe.md +38 -0
  354. package/docs/reference/admin-ui-api/pipes/has-permission-pipe.md +51 -0
  355. package/docs/reference/admin-ui-api/pipes/index.md +5 -0
  356. package/docs/reference/admin-ui-api/pipes/locale-currency-name-pipe.md +47 -0
  357. package/docs/reference/admin-ui-api/pipes/locale-currency-pipe.md +54 -0
  358. package/docs/reference/admin-ui-api/pipes/locale-date-pipe.md +48 -0
  359. package/docs/reference/admin-ui-api/pipes/locale-language-name-pipe.md +47 -0
  360. package/docs/reference/admin-ui-api/pipes/locale-region-name-pipe.md +47 -0
  361. package/docs/reference/admin-ui-api/pipes/time-ago-pipe.md +44 -0
  362. package/docs/reference/admin-ui-api/react-components/action-bar.md +36 -0
  363. package/docs/reference/admin-ui-api/react-components/card.md +36 -0
  364. package/docs/reference/admin-ui-api/react-components/cds-icon.md +34 -0
  365. package/docs/reference/admin-ui-api/react-components/form-field.md +42 -0
  366. package/docs/reference/admin-ui-api/react-components/index.md +5 -0
  367. package/docs/reference/admin-ui-api/react-components/link.md +34 -0
  368. package/docs/reference/admin-ui-api/react-components/page-block.md +36 -0
  369. package/docs/reference/admin-ui-api/react-components/page-detail-layout.md +36 -0
  370. package/docs/reference/admin-ui-api/react-components/rich-text-editor.md +42 -0
  371. package/docs/reference/admin-ui-api/react-extensions/index.md +5 -0
  372. package/docs/reference/admin-ui-api/react-extensions/react-custom-detail-component-config.md +41 -0
  373. package/docs/reference/admin-ui-api/react-extensions/react-data-table-component-config.md +48 -0
  374. package/docs/reference/admin-ui-api/react-extensions/register-react-custom-detail-component.md +23 -0
  375. package/docs/reference/admin-ui-api/react-extensions/register-react-data-table-component.md +55 -0
  376. package/docs/reference/admin-ui-api/react-extensions/register-react-form-input-component.md +26 -0
  377. package/docs/reference/admin-ui-api/react-extensions/register-react-route-component-options.md +18 -0
  378. package/docs/reference/admin-ui-api/react-extensions/register-react-route-component.md +22 -0
  379. package/docs/reference/admin-ui-api/react-hooks/index.md +5 -0
  380. package/docs/reference/admin-ui-api/react-hooks/use-detail-component-data.md +39 -0
  381. package/docs/reference/admin-ui-api/react-hooks/use-form-control.md +36 -0
  382. package/docs/reference/admin-ui-api/react-hooks/use-injector.md +39 -0
  383. package/docs/reference/admin-ui-api/react-hooks/use-lazy-query.md +74 -0
  384. package/docs/reference/admin-ui-api/react-hooks/use-mutation.md +62 -0
  385. package/docs/reference/admin-ui-api/react-hooks/use-page-metadata.md +36 -0
  386. package/docs/reference/admin-ui-api/react-hooks/use-query.md +59 -0
  387. package/docs/reference/admin-ui-api/react-hooks/use-rich-text-editor.md +30 -0
  388. package/docs/reference/admin-ui-api/react-hooks/use-route-params.md +29 -0
  389. package/docs/reference/admin-ui-api/routes/index.md +5 -0
  390. package/docs/reference/admin-ui-api/routes/register-route-component-options.md +28 -0
  391. package/docs/reference/admin-ui-api/routes/register-route-component.md +57 -0
  392. package/docs/reference/admin-ui-api/services/data-service.md +142 -0
  393. package/docs/reference/admin-ui-api/services/index.md +5 -0
  394. package/docs/reference/admin-ui-api/services/modal-service.md +199 -0
  395. package/docs/reference/admin-ui-api/services/notification-service.md +126 -0
  396. package/docs/reference/admin-ui-api/tabs/index.md +5 -0
  397. package/docs/reference/admin-ui-api/tabs/page-tab-config.md +70 -0
  398. package/docs/reference/admin-ui-api/tabs/register-page-tab.md +38 -0
  399. package/docs/reference/admin-ui-api/ui-devkit/admin-ui-extension.md +417 -0
  400. package/docs/reference/admin-ui-api/ui-devkit/compile-ui-extensions.md +22 -0
  401. package/docs/reference/admin-ui-api/ui-devkit/helpers.md +39 -0
  402. package/docs/reference/admin-ui-api/ui-devkit/index.md +5 -0
  403. package/docs/reference/admin-ui-api/ui-devkit/ui-devkit-client.md +160 -0
  404. package/docs/reference/admin-ui-api/ui-devkit/ui-extension-build-command.md +16 -0
  405. package/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-options.md +118 -0
  406. package/docs/reference/admin-ui-api/ui-devkit/ui-extension-compiler-process-argument.md +16 -0
  407. package/docs/reference/core-plugins/admin-ui-plugin/admin-ui-plugin-options.md +67 -0
  408. package/docs/reference/core-plugins/admin-ui-plugin/index.md +94 -0
  409. package/docs/reference/core-plugins/asset-server-plugin/asset-server-options.md +106 -0
  410. package/docs/reference/core-plugins/asset-server-plugin/cache-config.md +36 -0
  411. package/docs/reference/core-plugins/asset-server-plugin/hashed-asset-naming-strategy.md +47 -0
  412. package/docs/reference/core-plugins/asset-server-plugin/image-transform-mode.md +21 -0
  413. package/docs/reference/core-plugins/asset-server-plugin/image-transform-preset.md +57 -0
  414. package/docs/reference/core-plugins/asset-server-plugin/image-transform-strategy.md +144 -0
  415. package/docs/reference/core-plugins/asset-server-plugin/index.md +189 -0
  416. package/docs/reference/core-plugins/asset-server-plugin/local-asset-storage-strategy.md +74 -0
  417. package/docs/reference/core-plugins/asset-server-plugin/preset-only-strategy.md +118 -0
  418. package/docs/reference/core-plugins/asset-server-plugin/s3asset-storage-strategy.md +225 -0
  419. package/docs/reference/core-plugins/asset-server-plugin/sharp-asset-preview-strategy.md +118 -0
  420. package/docs/reference/core-plugins/dashboard-plugin/dashboard-plugin-options.md +43 -0
  421. package/docs/reference/core-plugins/dashboard-plugin/index.md +106 -0
  422. package/docs/reference/core-plugins/elasticsearch-plugin/elasticsearch-options.md +695 -0
  423. package/docs/reference/core-plugins/elasticsearch-plugin/index.md +193 -0
  424. package/docs/reference/core-plugins/email-plugin/email-event-handler-with-async-data.md +33 -0
  425. package/docs/reference/core-plugins/email-plugin/email-event-handler.md +299 -0
  426. package/docs/reference/core-plugins/email-plugin/email-event-listener.md +42 -0
  427. package/docs/reference/core-plugins/email-plugin/email-generator.md +78 -0
  428. package/docs/reference/core-plugins/email-plugin/email-plugin-options.md +154 -0
  429. package/docs/reference/core-plugins/email-plugin/email-plugin-types.md +276 -0
  430. package/docs/reference/core-plugins/email-plugin/email-send-event.md +34 -0
  431. package/docs/reference/core-plugins/email-plugin/email-sender.md +92 -0
  432. package/docs/reference/core-plugins/email-plugin/email-utils.md +54 -0
  433. package/docs/reference/core-plugins/email-plugin/index.md +309 -0
  434. package/docs/reference/core-plugins/email-plugin/template-loader.md +96 -0
  435. package/docs/reference/core-plugins/email-plugin/transport-options.md +241 -0
  436. package/docs/reference/core-plugins/graphiql-plugin/index.md +89 -0
  437. package/docs/reference/core-plugins/harden-plugin/default-vendure-complexity-estimator.md +30 -0
  438. package/docs/reference/core-plugins/harden-plugin/harden-plugin-options.md +106 -0
  439. package/docs/reference/core-plugins/harden-plugin/index.md +169 -0
  440. package/docs/reference/core-plugins/index.md +5 -0
  441. package/docs/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-plugin.md +211 -0
  442. package/docs/reference/core-plugins/job-queue-plugin/bull-mqjob-queue-strategy.md +93 -0
  443. package/docs/reference/core-plugins/job-queue-plugin/bull-mqplugin-options.md +142 -0
  444. package/docs/reference/core-plugins/job-queue-plugin/index.md +5 -0
  445. package/docs/reference/core-plugins/job-queue-plugin/pub-sub-job-queue-strategy.md +65 -0
  446. package/docs/reference/core-plugins/job-queue-plugin/pub-sub-plugin.md +36 -0
  447. package/docs/reference/core-plugins/payments-plugin/braintree-plugin.md +350 -0
  448. package/docs/reference/core-plugins/payments-plugin/index.md +5 -0
  449. package/docs/reference/core-plugins/payments-plugin/mollie-plugin.md +209 -0
  450. package/docs/reference/core-plugins/payments-plugin/stripe-plugin.md +355 -0
  451. package/docs/reference/core-plugins/sentry-plugin/index.md +158 -0
  452. package/docs/reference/core-plugins/sentry-plugin/sentry-plugin-options.md +32 -0
  453. package/docs/reference/core-plugins/sentry-plugin/sentry-service.md +47 -0
  454. package/docs/reference/core-plugins/stellate-plugin/index.md +277 -0
  455. package/docs/reference/core-plugins/stellate-plugin/purge-rule.md +91 -0
  456. package/docs/reference/core-plugins/stellate-plugin/stellate-plugin-options.md +65 -0
  457. package/docs/reference/core-plugins/stellate-plugin/stellate-service.md +71 -0
  458. package/docs/reference/core-plugins/telemetry-plugin/get-sdk-configuration.md +92 -0
  459. package/docs/reference/core-plugins/telemetry-plugin/index.md +131 -0
  460. package/docs/reference/core-plugins/telemetry-plugin/otel-logger.md +102 -0
  461. package/docs/reference/core-plugins/telemetry-plugin/register-method-hooks.md +46 -0
  462. package/docs/reference/core-plugins/telemetry-plugin/telemetry-plugin-options.md +77 -0
  463. package/docs/reference/dashboard/components/asset-gallery.md +127 -0
  464. package/docs/reference/dashboard/components/asset-picker-dialog.md +76 -0
  465. package/docs/reference/dashboard/components/channel-chip.md +22 -0
  466. package/docs/reference/dashboard/components/detail-page-button.md +49 -0
  467. package/docs/reference/dashboard/components/facet-value-chip.md +22 -0
  468. package/docs/reference/dashboard/components/facet-value-selector.md +85 -0
  469. package/docs/reference/dashboard/components/index.md +5 -0
  470. package/docs/reference/dashboard/components/permission-guard.md +63 -0
  471. package/docs/reference/dashboard/components/vendure-image.md +199 -0
  472. package/docs/reference/dashboard/detail-views/detail-page.md +91 -0
  473. package/docs/reference/dashboard/detail-views/index.md +5 -0
  474. package/docs/reference/dashboard/detail-views/use-detail-page.md +234 -0
  475. package/docs/reference/dashboard/detail-views/use-generated-form.md +105 -0
  476. package/docs/reference/dashboard/extensions-api/action-bar.md +66 -0
  477. package/docs/reference/dashboard/extensions-api/alerts.md +78 -0
  478. package/docs/reference/dashboard/extensions-api/data-tables.md +55 -0
  479. package/docs/reference/dashboard/extensions-api/define-dashboard-extension.md +142 -0
  480. package/docs/reference/dashboard/extensions-api/detail-forms.md +81 -0
  481. package/docs/reference/dashboard/extensions-api/form-components.md +188 -0
  482. package/docs/reference/dashboard/extensions-api/history-entries.md +246 -0
  483. package/docs/reference/dashboard/extensions-api/index.md +5 -0
  484. package/docs/reference/dashboard/extensions-api/login.md +113 -0
  485. package/docs/reference/dashboard/extensions-api/navigation.md +128 -0
  486. package/docs/reference/dashboard/extensions-api/page-blocks.md +143 -0
  487. package/docs/reference/dashboard/extensions-api/routes.md +69 -0
  488. package/docs/reference/dashboard/extensions-api/widgets.md +61 -0
  489. package/docs/reference/dashboard/form-components/affixed-input.md +34 -0
  490. package/docs/reference/dashboard/form-components/boolean-input.md +22 -0
  491. package/docs/reference/dashboard/form-components/checkbox-input.md +22 -0
  492. package/docs/reference/dashboard/form-components/date-time-input.md +22 -0
  493. package/docs/reference/dashboard/form-components/form-field-wrapper.md +80 -0
  494. package/docs/reference/dashboard/form-components/index.md +5 -0
  495. package/docs/reference/dashboard/form-components/money-input.md +23 -0
  496. package/docs/reference/dashboard/form-components/number-input.md +22 -0
  497. package/docs/reference/dashboard/form-components/password-input.md +22 -0
  498. package/docs/reference/dashboard/form-components/rich-text-input.md +22 -0
  499. package/docs/reference/dashboard/form-components/slug-input.md +57 -0
  500. package/docs/reference/dashboard/form-components/text-input.md +13 -0
  501. package/docs/reference/dashboard/form-components/textarea-input.md +22 -0
  502. package/docs/reference/dashboard/form-components/translatable-form-field-wrapper.md +70 -0
  503. package/docs/reference/dashboard/hooks/index.md +5 -0
  504. package/docs/reference/dashboard/hooks/use-alerts.md +65 -0
  505. package/docs/reference/dashboard/hooks/use-auth.md +84 -0
  506. package/docs/reference/dashboard/hooks/use-channel.md +72 -0
  507. package/docs/reference/dashboard/hooks/use-custom-field-config.md +24 -0
  508. package/docs/reference/dashboard/hooks/use-display-locale.md +32 -0
  509. package/docs/reference/dashboard/hooks/use-drag-and-drop.md +22 -0
  510. package/docs/reference/dashboard/hooks/use-local-format.md +30 -0
  511. package/docs/reference/dashboard/hooks/use-paginated-list.md +29 -0
  512. package/docs/reference/dashboard/hooks/use-permissions.md +25 -0
  513. package/docs/reference/dashboard/hooks/use-sorted-languages.md +30 -0
  514. package/docs/reference/dashboard/hooks/use-ui-language-loader.md +18 -0
  515. package/docs/reference/dashboard/hooks/use-widget-filters.md +16 -0
  516. package/docs/reference/dashboard/list-views/bulk-actions.md +199 -0
  517. package/docs/reference/dashboard/list-views/data-table-cell-component.md +45 -0
  518. package/docs/reference/dashboard/list-views/data-table.md +209 -0
  519. package/docs/reference/dashboard/list-views/index.md +5 -0
  520. package/docs/reference/dashboard/list-views/list-page.md +493 -0
  521. package/docs/reference/dashboard/list-views/paginated-list-data-table.md +303 -0
  522. package/docs/reference/dashboard/page-layout/index.md +54 -0
  523. package/docs/reference/dashboard/page-layout/page-action-bar.md +62 -0
  524. package/docs/reference/dashboard/page-layout/page-block.md +137 -0
  525. package/docs/reference/dashboard/page-layout/page-title.md +22 -0
  526. package/docs/reference/dashboard/page-layout/page.md +100 -0
  527. package/docs/reference/dashboard/page-layout/use-page-block.md +32 -0
  528. package/docs/reference/dashboard/vite-plugin/index.md +5 -0
  529. package/docs/reference/dashboard/vite-plugin/vendure-dashboard-plugin.md +356 -0
  530. package/docs/reference/graphql-api/_index.md +16 -0
  531. package/docs/reference/graphql-api/admin/_index.md +13 -0
  532. package/docs/reference/graphql-api/admin/enums.md +1142 -0
  533. package/docs/reference/graphql-api/admin/input-types.md +4631 -0
  534. package/docs/reference/graphql-api/admin/mutations.md +1985 -0
  535. package/docs/reference/graphql-api/admin/object-types.md +4515 -0
  536. package/docs/reference/graphql-api/admin/queries.md +760 -0
  537. package/docs/reference/graphql-api/shop/_index.md +13 -0
  538. package/docs/reference/graphql-api/shop/enums.md +1072 -0
  539. package/docs/reference/graphql-api/shop/input-types.md +1192 -0
  540. package/docs/reference/graphql-api/shop/mutations.md +431 -0
  541. package/docs/reference/graphql-api/shop/object-types.md +3406 -0
  542. package/docs/reference/graphql-api/shop/queries.md +247 -0
  543. package/docs/reference/index.mdx +38 -0
  544. package/docs/reference/links.webp +0 -0
  545. package/docs/reference/typescript-api/_index.md +13 -0
  546. package/docs/reference/typescript-api/assets/asset-naming-strategy.md +56 -0
  547. package/docs/reference/typescript-api/assets/asset-options.md +58 -0
  548. package/docs/reference/typescript-api/assets/asset-preview-strategy.md +45 -0
  549. package/docs/reference/typescript-api/assets/asset-storage-strategy.md +84 -0
  550. package/docs/reference/typescript-api/assets/default-asset-naming-strategy.md +39 -0
  551. package/docs/reference/typescript-api/assets/index.md +5 -0
  552. package/docs/reference/typescript-api/auth/auth-options.md +165 -0
  553. package/docs/reference/typescript-api/auth/authentication-strategy.md +97 -0
  554. package/docs/reference/typescript-api/auth/bcrypt-password-hashing-strategy.md +38 -0
  555. package/docs/reference/typescript-api/auth/cookie-options.md +108 -0
  556. package/docs/reference/typescript-api/auth/default-password-validation-strategy.md +44 -0
  557. package/docs/reference/typescript-api/auth/default-session-cache-strategy.md +73 -0
  558. package/docs/reference/typescript-api/auth/default-verification-token-strategy.md +47 -0
  559. package/docs/reference/typescript-api/auth/external-authentication-service.md +98 -0
  560. package/docs/reference/typescript-api/auth/in-memory-session-cache-strategy.md +63 -0
  561. package/docs/reference/typescript-api/auth/index.md +5 -0
  562. package/docs/reference/typescript-api/auth/native-authentication-strategy.md +58 -0
  563. package/docs/reference/typescript-api/auth/noop-session-cache-strategy.md +51 -0
  564. package/docs/reference/typescript-api/auth/password-hashing-strategy.md +45 -0
  565. package/docs/reference/typescript-api/auth/password-validation-strategy.md +43 -0
  566. package/docs/reference/typescript-api/auth/permission-definition.md +269 -0
  567. package/docs/reference/typescript-api/auth/session-cache-strategy.md +275 -0
  568. package/docs/reference/typescript-api/auth/superadmin-credentials.md +36 -0
  569. package/docs/reference/typescript-api/auth/verification-token-strategy.md +45 -0
  570. package/docs/reference/typescript-api/cache/cache-config.md +44 -0
  571. package/docs/reference/typescript-api/cache/cache-service.md +76 -0
  572. package/docs/reference/typescript-api/cache/cache-strategy.md +103 -0
  573. package/docs/reference/typescript-api/cache/default-cache-plugin.md +73 -0
  574. package/docs/reference/typescript-api/cache/index.md +79 -0
  575. package/docs/reference/typescript-api/cache/redis-cache-plugin.md +85 -0
  576. package/docs/reference/typescript-api/cache/redis-cache-strategy.md +75 -0
  577. package/docs/reference/typescript-api/cache/request-context-cache-service.md +54 -0
  578. package/docs/reference/typescript-api/cache/self-refreshing-cache.md +152 -0
  579. package/docs/reference/typescript-api/cache/sql-cache-strategy.md +87 -0
  580. package/docs/reference/typescript-api/common/admin-ui/admin-ui-app-config.md +43 -0
  581. package/docs/reference/typescript-api/common/admin-ui/admin-ui-app-dev-mode-config.md +47 -0
  582. package/docs/reference/typescript-api/common/admin-ui/admin-ui-config.md +139 -0
  583. package/docs/reference/typescript-api/common/admin-ui/index.md +5 -0
  584. package/docs/reference/typescript-api/common/async-queue.md +38 -0
  585. package/docs/reference/typescript-api/common/bootstrap.md +129 -0
  586. package/docs/reference/typescript-api/common/currency-code.md +174 -0
  587. package/docs/reference/typescript-api/common/entity-relation-paths.md +34 -0
  588. package/docs/reference/typescript-api/common/i18n-service.md +74 -0
  589. package/docs/reference/typescript-api/common/id.md +17 -0
  590. package/docs/reference/typescript-api/common/index.md +5 -0
  591. package/docs/reference/typescript-api/common/injectable-strategy.md +48 -0
  592. package/docs/reference/typescript-api/common/injector.md +47 -0
  593. package/docs/reference/typescript-api/common/job-state.md +23 -0
  594. package/docs/reference/typescript-api/common/json-compatible.md +23 -0
  595. package/docs/reference/typescript-api/common/language-code.md +177 -0
  596. package/docs/reference/typescript-api/common/middleware.md +72 -0
  597. package/docs/reference/typescript-api/common/paginated-list.md +36 -0
  598. package/docs/reference/typescript-api/common/permission.md +136 -0
  599. package/docs/reference/typescript-api/common/price-calculation-result.md +36 -0
  600. package/docs/reference/typescript-api/common/process-context.md +55 -0
  601. package/docs/reference/typescript-api/common/vendure_version.md +22 -0
  602. package/docs/reference/typescript-api/configurable-operation-def/config-arg-type.md +22 -0
  603. package/docs/reference/typescript-api/configurable-operation-def/config-args.md +89 -0
  604. package/docs/reference/typescript-api/configurable-operation-def/configurable-operation-def-options.md +57 -0
  605. package/docs/reference/typescript-api/configurable-operation-def/default-form-component-id.md +34 -0
  606. package/docs/reference/typescript-api/configurable-operation-def/default-form-config-hash.md +137 -0
  607. package/docs/reference/typescript-api/configurable-operation-def/index.md +149 -0
  608. package/docs/reference/typescript-api/configurable-operation-def/localized-string-array.md +28 -0
  609. package/docs/reference/typescript-api/configuration/api-options.md +159 -0
  610. package/docs/reference/typescript-api/configuration/collection-filter.md +76 -0
  611. package/docs/reference/typescript-api/configuration/default-config.md +13 -0
  612. package/docs/reference/typescript-api/configuration/default-slug-strategy.md +46 -0
  613. package/docs/reference/typescript-api/configuration/entity-duplicator.md +195 -0
  614. package/docs/reference/typescript-api/configuration/entity-id-decorator.md +24 -0
  615. package/docs/reference/typescript-api/configuration/entity-id-strategy.md +168 -0
  616. package/docs/reference/typescript-api/configuration/entity-options.md +153 -0
  617. package/docs/reference/typescript-api/configuration/index.md +5 -0
  618. package/docs/reference/typescript-api/configuration/merge-config.md +49 -0
  619. package/docs/reference/typescript-api/configuration/product-variant-price-selection-strategy.md +71 -0
  620. package/docs/reference/typescript-api/configuration/product-variant-price-update-strategy.md +185 -0
  621. package/docs/reference/typescript-api/configuration/runtime-vendure-config.md +111 -0
  622. package/docs/reference/typescript-api/configuration/settings-store-fields.md +29 -0
  623. package/docs/reference/typescript-api/configuration/slug-strategy.md +47 -0
  624. package/docs/reference/typescript-api/configuration/system-options.md +50 -0
  625. package/docs/reference/typescript-api/configuration/trust-proxy-options.md +19 -0
  626. package/docs/reference/typescript-api/configuration/vendure-config.md +168 -0
  627. package/docs/reference/typescript-api/custom-fields/custom-field-config.md +25 -0
  628. package/docs/reference/typescript-api/custom-fields/custom-field-type.md +42 -0
  629. package/docs/reference/typescript-api/custom-fields/index.md +70 -0
  630. package/docs/reference/typescript-api/custom-fields/struct-custom-field-config.md +21 -0
  631. package/docs/reference/typescript-api/custom-fields/struct-field-config.md +41 -0
  632. package/docs/reference/typescript-api/custom-fields/typed-custom-single-field-config.md +24 -0
  633. package/docs/reference/typescript-api/data-access/calculated-property-subscriber.md +38 -0
  634. package/docs/reference/typescript-api/data-access/calculated.md +62 -0
  635. package/docs/reference/typescript-api/data-access/entity-hydrator.md +103 -0
  636. package/docs/reference/typescript-api/data-access/get-entity-or-throw-options.md +53 -0
  637. package/docs/reference/typescript-api/data-access/hydrate-options.md +40 -0
  638. package/docs/reference/typescript-api/data-access/index.md +5 -0
  639. package/docs/reference/typescript-api/data-access/list-query-builder.md +239 -0
  640. package/docs/reference/typescript-api/data-access/transactional-connection.md +173 -0
  641. package/docs/reference/typescript-api/default-search-plugin/default-search-plugin-init-options.md +126 -0
  642. package/docs/reference/typescript-api/default-search-plugin/index.md +64 -0
  643. package/docs/reference/typescript-api/default-search-plugin/mysql-search-strategy.md +56 -0
  644. package/docs/reference/typescript-api/default-search-plugin/postgres-search-strategy.md +56 -0
  645. package/docs/reference/typescript-api/default-search-plugin/search-strategy.md +58 -0
  646. package/docs/reference/typescript-api/default-search-plugin/sqlite-search-strategy.md +57 -0
  647. package/docs/reference/typescript-api/entities/address.md +124 -0
  648. package/docs/reference/typescript-api/entities/administrator.md +78 -0
  649. package/docs/reference/typescript-api/entities/anonymous-session.md +34 -0
  650. package/docs/reference/typescript-api/entities/asset.md +135 -0
  651. package/docs/reference/typescript-api/entities/authenticated-session.md +48 -0
  652. package/docs/reference/typescript-api/entities/authentication-method.md +156 -0
  653. package/docs/reference/typescript-api/entities/channel.md +233 -0
  654. package/docs/reference/typescript-api/entities/collection.md +152 -0
  655. package/docs/reference/typescript-api/entities/country.md +40 -0
  656. package/docs/reference/typescript-api/entities/customer-group.md +63 -0
  657. package/docs/reference/typescript-api/entities/customer-history-entry.md +40 -0
  658. package/docs/reference/typescript-api/entities/customer.md +122 -0
  659. package/docs/reference/typescript-api/entities/facet-value.md +98 -0
  660. package/docs/reference/typescript-api/entities/facet.md +89 -0
  661. package/docs/reference/typescript-api/entities/fulfillment.md +84 -0
  662. package/docs/reference/typescript-api/entities/global-settings.md +66 -0
  663. package/docs/reference/typescript-api/entities/history-entry.md +66 -0
  664. package/docs/reference/typescript-api/entities/index.md +5 -0
  665. package/docs/reference/typescript-api/entities/interfaces.md +125 -0
  666. package/docs/reference/typescript-api/entities/order-history-entry.md +40 -0
  667. package/docs/reference/typescript-api/entities/order-line-reference.md +174 -0
  668. package/docs/reference/typescript-api/entities/order-line.md +344 -0
  669. package/docs/reference/typescript-api/entities/order-modification.md +103 -0
  670. package/docs/reference/typescript-api/entities/order.md +284 -0
  671. package/docs/reference/typescript-api/entities/orderable-asset.md +61 -0
  672. package/docs/reference/typescript-api/entities/payment-method.md +94 -0
  673. package/docs/reference/typescript-api/entities/payment.md +96 -0
  674. package/docs/reference/typescript-api/entities/product-option-group.md +84 -0
  675. package/docs/reference/typescript-api/entities/product-option.md +90 -0
  676. package/docs/reference/typescript-api/entities/product-variant-price.md +70 -0
  677. package/docs/reference/typescript-api/entities/product-variant.md +251 -0
  678. package/docs/reference/typescript-api/entities/product.md +134 -0
  679. package/docs/reference/typescript-api/entities/promotion.md +190 -0
  680. package/docs/reference/typescript-api/entities/province.md +39 -0
  681. package/docs/reference/typescript-api/entities/refund.md +120 -0
  682. package/docs/reference/typescript-api/entities/region.md +87 -0
  683. package/docs/reference/typescript-api/entities/role.md +62 -0
  684. package/docs/reference/typescript-api/entities/seller.md +63 -0
  685. package/docs/reference/typescript-api/entities/session.md +87 -0
  686. package/docs/reference/typescript-api/entities/settings-store-entry.md +57 -0
  687. package/docs/reference/typescript-api/entities/shipping-line.md +150 -0
  688. package/docs/reference/typescript-api/entities/shipping-method.md +123 -0
  689. package/docs/reference/typescript-api/entities/stock-level.md +87 -0
  690. package/docs/reference/typescript-api/entities/stock-location.md +76 -0
  691. package/docs/reference/typescript-api/entities/stock-movement.md +270 -0
  692. package/docs/reference/typescript-api/entities/surcharge.md +102 -0
  693. package/docs/reference/typescript-api/entities/tag.md +40 -0
  694. package/docs/reference/typescript-api/entities/tax-category.md +68 -0
  695. package/docs/reference/typescript-api/entities/tax-rate.md +138 -0
  696. package/docs/reference/typescript-api/entities/user.md +111 -0
  697. package/docs/reference/typescript-api/entities/vendure-entity.md +49 -0
  698. package/docs/reference/typescript-api/entities/zone.md +78 -0
  699. package/docs/reference/typescript-api/errors/error-handler-strategy.md +88 -0
  700. package/docs/reference/typescript-api/errors/error-result-union.md +30 -0
  701. package/docs/reference/typescript-api/errors/error-types.md +197 -0
  702. package/docs/reference/typescript-api/errors/i18n-error.md +39 -0
  703. package/docs/reference/typescript-api/errors/index.md +5 -0
  704. package/docs/reference/typescript-api/errors/is-graph-ql-error-result.md +40 -0
  705. package/docs/reference/typescript-api/events/blocking-event-handler-options.md +57 -0
  706. package/docs/reference/typescript-api/events/event-bus.md +136 -0
  707. package/docs/reference/typescript-api/events/event-types.md +1689 -0
  708. package/docs/reference/typescript-api/events/index.md +5 -0
  709. package/docs/reference/typescript-api/events/vendure-entity-event.md +57 -0
  710. package/docs/reference/typescript-api/events/vendure-event.md +35 -0
  711. package/docs/reference/typescript-api/fulfillment/fulfillment-handler.md +173 -0
  712. package/docs/reference/typescript-api/fulfillment/fulfillment-process.md +71 -0
  713. package/docs/reference/typescript-api/fulfillment/fulfillment-state.md +21 -0
  714. package/docs/reference/typescript-api/fulfillment/fulfillment-states.md +18 -0
  715. package/docs/reference/typescript-api/fulfillment/fulfillment-transition-data.md +41 -0
  716. package/docs/reference/typescript-api/fulfillment/index.md +5 -0
  717. package/docs/reference/typescript-api/health-check/health-check-registry-service.md +70 -0
  718. package/docs/reference/typescript-api/health-check/health-check-strategy.md +70 -0
  719. package/docs/reference/typescript-api/health-check/http-health-check-strategy.md +61 -0
  720. package/docs/reference/typescript-api/health-check/index.md +5 -0
  721. package/docs/reference/typescript-api/health-check/type-ormhealth-check-strategy.md +64 -0
  722. package/docs/reference/typescript-api/import-export/asset-import-strategy.md +46 -0
  723. package/docs/reference/typescript-api/import-export/asset-importer.md +32 -0
  724. package/docs/reference/typescript-api/import-export/default-asset-import-strategy.md +48 -0
  725. package/docs/reference/typescript-api/import-export/fast-importer-service.md +67 -0
  726. package/docs/reference/typescript-api/import-export/import-export-options.md +36 -0
  727. package/docs/reference/typescript-api/import-export/import-parser.md +280 -0
  728. package/docs/reference/typescript-api/import-export/importer.md +54 -0
  729. package/docs/reference/typescript-api/import-export/index.md +5 -0
  730. package/docs/reference/typescript-api/import-export/initial-data.md +71 -0
  731. package/docs/reference/typescript-api/import-export/populate.md +71 -0
  732. package/docs/reference/typescript-api/import-export/populator.md +38 -0
  733. package/docs/reference/typescript-api/job-queue/default-job-queue-plugin.md +245 -0
  734. package/docs/reference/typescript-api/job-queue/in-memory-job-buffer-storage-strategy.md +55 -0
  735. package/docs/reference/typescript-api/job-queue/in-memory-job-queue-strategy.md +110 -0
  736. package/docs/reference/typescript-api/job-queue/index.md +84 -0
  737. package/docs/reference/typescript-api/job-queue/inspectable-job-queue-strategy.md +60 -0
  738. package/docs/reference/typescript-api/job-queue/job-buffer-storage-strategy.md +78 -0
  739. package/docs/reference/typescript-api/job-queue/job-buffer.md +119 -0
  740. package/docs/reference/typescript-api/job-queue/job-queue-options.md +56 -0
  741. package/docs/reference/typescript-api/job-queue/job-queue-service.md +128 -0
  742. package/docs/reference/typescript-api/job-queue/job-queue-strategy.md +59 -0
  743. package/docs/reference/typescript-api/job-queue/job.md +195 -0
  744. package/docs/reference/typescript-api/job-queue/polling-job-queue-strategy.md +122 -0
  745. package/docs/reference/typescript-api/job-queue/sql-job-queue-strategy.md +84 -0
  746. package/docs/reference/typescript-api/job-queue/subscribable-job.md +44 -0
  747. package/docs/reference/typescript-api/job-queue/types.md +199 -0
  748. package/docs/reference/typescript-api/logger/default-logger.md +81 -0
  749. package/docs/reference/typescript-api/logger/index.md +120 -0
  750. package/docs/reference/typescript-api/logger/log-level.md +30 -0
  751. package/docs/reference/typescript-api/logger/vendure-logger.md +60 -0
  752. package/docs/reference/typescript-api/migration/generate-migration.md +28 -0
  753. package/docs/reference/typescript-api/migration/index.md +5 -0
  754. package/docs/reference/typescript-api/migration/migration-options.md +36 -0
  755. package/docs/reference/typescript-api/migration/revert-last-migration.md +23 -0
  756. package/docs/reference/typescript-api/migration/run-migrations.md +23 -0
  757. package/docs/reference/typescript-api/money/big-int-money-strategy.md +68 -0
  758. package/docs/reference/typescript-api/money/default-money-strategy.md +47 -0
  759. package/docs/reference/typescript-api/money/index.md +5 -0
  760. package/docs/reference/typescript-api/money/money-decorator.md +23 -0
  761. package/docs/reference/typescript-api/money/money-strategy.md +116 -0
  762. package/docs/reference/typescript-api/money/round-money.md +26 -0
  763. package/docs/reference/typescript-api/orders/active-order-service.md +69 -0
  764. package/docs/reference/typescript-api/orders/active-order-strategy.md +203 -0
  765. package/docs/reference/typescript-api/orders/changed-price-handling-strategy.md +51 -0
  766. package/docs/reference/typescript-api/orders/custom-order-states.md +18 -0
  767. package/docs/reference/typescript-api/orders/default-active-order-strategy.md +52 -0
  768. package/docs/reference/typescript-api/orders/default-guest-checkout-strategy.md +93 -0
  769. package/docs/reference/typescript-api/orders/default-order-item-price-calculation-strategy.md +33 -0
  770. package/docs/reference/typescript-api/orders/default-order-placed-strategy.md +33 -0
  771. package/docs/reference/typescript-api/orders/default-stock-allocation-strategy.md +33 -0
  772. package/docs/reference/typescript-api/orders/guest-checkout-strategy.md +56 -0
  773. package/docs/reference/typescript-api/orders/index.md +5 -0
  774. package/docs/reference/typescript-api/orders/merge-strategies.md +114 -0
  775. package/docs/reference/typescript-api/orders/order-by-code-access-strategy.md +91 -0
  776. package/docs/reference/typescript-api/orders/order-code-strategy.md +88 -0
  777. package/docs/reference/typescript-api/orders/order-interceptor.md +250 -0
  778. package/docs/reference/typescript-api/orders/order-item-price-calculation-strategy.md +91 -0
  779. package/docs/reference/typescript-api/orders/order-merge-strategy.md +80 -0
  780. package/docs/reference/typescript-api/orders/order-options.md +145 -0
  781. package/docs/reference/typescript-api/orders/order-placed-strategy.md +54 -0
  782. package/docs/reference/typescript-api/orders/order-process.md +271 -0
  783. package/docs/reference/typescript-api/orders/order-seller-strategy.md +124 -0
  784. package/docs/reference/typescript-api/orders/stock-allocation-strategy.md +46 -0
  785. package/docs/reference/typescript-api/payment/default-payment-process.md +13 -0
  786. package/docs/reference/typescript-api/payment/default-refund-process.md +13 -0
  787. package/docs/reference/typescript-api/payment/dummy-payment-handler.md +31 -0
  788. package/docs/reference/typescript-api/payment/index.md +5 -0
  789. package/docs/reference/typescript-api/payment/payment-method-config-options.md +69 -0
  790. package/docs/reference/typescript-api/payment/payment-method-eligibility-checker.md +95 -0
  791. package/docs/reference/typescript-api/payment/payment-method-handler.md +83 -0
  792. package/docs/reference/typescript-api/payment/payment-method-types.md +386 -0
  793. package/docs/reference/typescript-api/payment/payment-options.md +57 -0
  794. package/docs/reference/typescript-api/payment/payment-process.md +62 -0
  795. package/docs/reference/typescript-api/payment/payment-state.md +20 -0
  796. package/docs/reference/typescript-api/payment/payment-states.md +18 -0
  797. package/docs/reference/typescript-api/payment/payment-transition-data.md +42 -0
  798. package/docs/reference/typescript-api/payment/refund-process.md +55 -0
  799. package/docs/reference/typescript-api/payment/refund-state.md +16 -0
  800. package/docs/reference/typescript-api/payment/refund-states.md +18 -0
  801. package/docs/reference/typescript-api/payment/refund-transition-data.md +41 -0
  802. package/docs/reference/typescript-api/plugin/index.md +5 -0
  803. package/docs/reference/typescript-api/plugin/plugin-common-module.md +28 -0
  804. package/docs/reference/typescript-api/plugin/plugin-utilities.md +96 -0
  805. package/docs/reference/typescript-api/plugin/vendure-plugin-metadata.md +147 -0
  806. package/docs/reference/typescript-api/plugin/vendure-plugin.md +52 -0
  807. package/docs/reference/typescript-api/products-stock/catalog-options.md +70 -0
  808. package/docs/reference/typescript-api/products-stock/default-product-variant-price-calculation-strategy.md +38 -0
  809. package/docs/reference/typescript-api/products-stock/default-stock-display-strategy.md +40 -0
  810. package/docs/reference/typescript-api/products-stock/default-stock-location-strategy.md +47 -0
  811. package/docs/reference/typescript-api/products-stock/index.md +5 -0
  812. package/docs/reference/typescript-api/products-stock/multi-channel-stock-location-strategy.md +47 -0
  813. package/docs/reference/typescript-api/products-stock/product-variant-price-calculation-strategy.md +95 -0
  814. package/docs/reference/typescript-api/products-stock/stock-display-strategy.md +47 -0
  815. package/docs/reference/typescript-api/products-stock/stock-location-strategy.md +157 -0
  816. package/docs/reference/typescript-api/promotions/facet-value-checker.md +78 -0
  817. package/docs/reference/typescript-api/promotions/index.md +5 -0
  818. package/docs/reference/typescript-api/promotions/promotion-action.md +454 -0
  819. package/docs/reference/typescript-api/promotions/promotion-condition.md +117 -0
  820. package/docs/reference/typescript-api/promotions/promotion-options.md +35 -0
  821. package/docs/reference/typescript-api/request/allow-decorator.md +53 -0
  822. package/docs/reference/typescript-api/request/api-decorator.md +28 -0
  823. package/docs/reference/typescript-api/request/api-type.md +16 -0
  824. package/docs/reference/typescript-api/request/ctx-decorator.md +23 -0
  825. package/docs/reference/typescript-api/request/index.md +5 -0
  826. package/docs/reference/typescript-api/request/relations-decorator.md +116 -0
  827. package/docs/reference/typescript-api/request/request-context-service.md +47 -0
  828. package/docs/reference/typescript-api/request/request-context.md +205 -0
  829. package/docs/reference/typescript-api/request/transaction-decorator.md +82 -0
  830. package/docs/reference/typescript-api/scheduled-tasks/clean-sessions-task.md +40 -0
  831. package/docs/reference/typescript-api/scheduled-tasks/default-scheduler-plugin.md +86 -0
  832. package/docs/reference/typescript-api/scheduled-tasks/default-scheduler-strategy.md +76 -0
  833. package/docs/reference/typescript-api/scheduled-tasks/index.md +5 -0
  834. package/docs/reference/typescript-api/scheduled-tasks/scheduled-task.md +196 -0
  835. package/docs/reference/typescript-api/scheduled-tasks/scheduler-options.md +47 -0
  836. package/docs/reference/typescript-api/scheduled-tasks/scheduler-service.md +62 -0
  837. package/docs/reference/typescript-api/scheduled-tasks/scheduler-strategy.md +141 -0
  838. package/docs/reference/typescript-api/service-helpers/entity-duplicator-service.md +43 -0
  839. package/docs/reference/typescript-api/service-helpers/index.md +5 -0
  840. package/docs/reference/typescript-api/service-helpers/order-calculator.md +54 -0
  841. package/docs/reference/typescript-api/service-helpers/order-modifier.md +91 -0
  842. package/docs/reference/typescript-api/service-helpers/product-price-applicator.md +62 -0
  843. package/docs/reference/typescript-api/service-helpers/slug-validator.md +86 -0
  844. package/docs/reference/typescript-api/service-helpers/translatable-saver.md +66 -0
  845. package/docs/reference/typescript-api/service-helpers/translator-service.md +63 -0
  846. package/docs/reference/typescript-api/services/administrator-service.md +71 -0
  847. package/docs/reference/typescript-api/services/asset-service.md +177 -0
  848. package/docs/reference/typescript-api/services/auth-service.md +54 -0
  849. package/docs/reference/typescript-api/services/channel-service.md +111 -0
  850. package/docs/reference/typescript-api/services/collection-service.md +186 -0
  851. package/docs/reference/typescript-api/services/country-service.md +71 -0
  852. package/docs/reference/typescript-api/services/customer-group-service.md +77 -0
  853. package/docs/reference/typescript-api/services/customer-service.md +203 -0
  854. package/docs/reference/typescript-api/services/entity-slug-service.md +37 -0
  855. package/docs/reference/typescript-api/services/facet-service.md +95 -0
  856. package/docs/reference/typescript-api/services/facet-value-service.md +104 -0
  857. package/docs/reference/typescript-api/services/fulfillment-service.md +69 -0
  858. package/docs/reference/typescript-api/services/global-settings-service.md +41 -0
  859. package/docs/reference/typescript-api/services/history-service.md +172 -0
  860. package/docs/reference/typescript-api/services/index.md +5 -0
  861. package/docs/reference/typescript-api/services/initializer-service.md +36 -0
  862. package/docs/reference/typescript-api/services/order-service.md +440 -0
  863. package/docs/reference/typescript-api/services/order-testing-service.md +44 -0
  864. package/docs/reference/typescript-api/services/payment-method-service.md +105 -0
  865. package/docs/reference/typescript-api/services/payment-service.md +105 -0
  866. package/docs/reference/typescript-api/services/product-option-group-service.md +67 -0
  867. package/docs/reference/typescript-api/services/product-option-service.md +64 -0
  868. package/docs/reference/typescript-api/services/product-service.md +111 -0
  869. package/docs/reference/typescript-api/services/product-variant-service.md +179 -0
  870. package/docs/reference/typescript-api/services/promotion-service.md +127 -0
  871. package/docs/reference/typescript-api/services/province-service.md +59 -0
  872. package/docs/reference/typescript-api/services/role-service.md +113 -0
  873. package/docs/reference/typescript-api/services/search-service.md +37 -0
  874. package/docs/reference/typescript-api/services/seller-service.md +65 -0
  875. package/docs/reference/typescript-api/services/session-service.md +105 -0
  876. package/docs/reference/typescript-api/services/settings-store-service.md +194 -0
  877. package/docs/reference/typescript-api/services/shipping-method-service.md +95 -0
  878. package/docs/reference/typescript-api/services/slug-service.md +35 -0
  879. package/docs/reference/typescript-api/services/stock-level-service.md +62 -0
  880. package/docs/reference/typescript-api/services/stock-location-service.md +115 -0
  881. package/docs/reference/typescript-api/services/stock-movement-service.md +95 -0
  882. package/docs/reference/typescript-api/services/tag-service.md +71 -0
  883. package/docs/reference/typescript-api/services/tax-category-service.md +59 -0
  884. package/docs/reference/typescript-api/services/tax-rate-service.md +66 -0
  885. package/docs/reference/typescript-api/services/user-service.md +132 -0
  886. package/docs/reference/typescript-api/services/zone-service.md +77 -0
  887. package/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-options.md +48 -0
  888. package/docs/reference/typescript-api/settings-store/cleanup-orphaned-settings-store-entries-result.md +41 -0
  889. package/docs/reference/typescript-api/settings-store/index.md +38 -0
  890. package/docs/reference/typescript-api/settings-store/orphaned-settings-store-entry.md +48 -0
  891. package/docs/reference/typescript-api/settings-store/set-settings-store-value-result.md +42 -0
  892. package/docs/reference/typescript-api/settings-store/settings-store-field-config.md +92 -0
  893. package/docs/reference/typescript-api/settings-store/settings-store-registration.md +36 -0
  894. package/docs/reference/typescript-api/settings-store/settings-store-scope-function.md +35 -0
  895. package/docs/reference/typescript-api/settings-store/settings-store-scopes.md +36 -0
  896. package/docs/reference/typescript-api/shipping/check-shipping-eligibility-checker-fn.md +27 -0
  897. package/docs/reference/typescript-api/shipping/default-shipping-line-assignment-strategy.md +33 -0
  898. package/docs/reference/typescript-api/shipping/index.md +5 -0
  899. package/docs/reference/typescript-api/shipping/shipping-calculator.md +121 -0
  900. package/docs/reference/typescript-api/shipping/shipping-eligibility-checker-config.md +39 -0
  901. package/docs/reference/typescript-api/shipping/shipping-eligibility-checker.md +60 -0
  902. package/docs/reference/typescript-api/shipping/shipping-line-assignment-strategy.md +75 -0
  903. package/docs/reference/typescript-api/shipping/shipping-options.md +63 -0
  904. package/docs/reference/typescript-api/shipping/should-run-check-fn.md +44 -0
  905. package/docs/reference/typescript-api/state-machine/fsm.md +66 -0
  906. package/docs/reference/typescript-api/state-machine/index.md +5 -0
  907. package/docs/reference/typescript-api/state-machine/state-machine-config.md +103 -0
  908. package/docs/reference/typescript-api/state-machine/transitions.md +43 -0
  909. package/docs/reference/typescript-api/tax/address-based-tax-zone-strategy.md +57 -0
  910. package/docs/reference/typescript-api/tax/default-tax-line-calculation-strategy.md +33 -0
  911. package/docs/reference/typescript-api/tax/default-tax-zone-strategy.md +35 -0
  912. package/docs/reference/typescript-api/tax/index.md +5 -0
  913. package/docs/reference/typescript-api/tax/tax-line-calculation-strategy.md +90 -0
  914. package/docs/reference/typescript-api/tax/tax-options.md +35 -0
  915. package/docs/reference/typescript-api/tax/tax-zone-strategy.md +54 -0
  916. package/docs/reference/typescript-api/telemetry/index.md +5 -0
  917. package/docs/reference/typescript-api/telemetry/instrument.md +47 -0
  918. package/docs/reference/typescript-api/telemetry/instrumentation-strategy.md +35 -0
  919. package/docs/reference/typescript-api/telemetry/wrapped-method-args.md +56 -0
  920. package/docs/reference/typescript-api/testing/create-error-result-guard.md +33 -0
  921. package/docs/reference/typescript-api/testing/create-test-environment.md +47 -0
  922. package/docs/reference/typescript-api/testing/error-result-guard.md +73 -0
  923. package/docs/reference/typescript-api/testing/get-superadmin-context.md +23 -0
  924. package/docs/reference/typescript-api/testing/index.md +5 -0
  925. package/docs/reference/typescript-api/testing/register-initializer.md +27 -0
  926. package/docs/reference/typescript-api/testing/simple-graph-qlclient.md +123 -0
  927. package/docs/reference/typescript-api/testing/test-config.md +30 -0
  928. package/docs/reference/typescript-api/testing/test-db-initializer.md +60 -0
  929. package/docs/reference/typescript-api/testing/test-environment.md +42 -0
  930. package/docs/reference/typescript-api/testing/test-server-options.md +47 -0
  931. package/docs/reference/typescript-api/testing/test-server.md +60 -0
  932. package/docs/reference/typescript-api/testing/testing-logger.md +140 -0
  933. package/docs/reference/typescript-api/worker/bootstrap-worker.md +76 -0
  934. package/docs/reference/typescript-api/worker/index.md +5 -0
  935. package/docs/reference/typescript-api/worker/vendure-worker.md +50 -0
  936. package/docs/reference/typescript-api/worker/worker-health-check-config.md +41 -0
  937. package/docs/user-guide/catalog/collections.md +27 -0
  938. package/docs/user-guide/catalog/facets.md +34 -0
  939. package/docs/user-guide/catalog/product-variants.png +0 -0
  940. package/docs/user-guide/catalog/products.md +35 -0
  941. package/docs/user-guide/catalog/screen-facet-add.webp +0 -0
  942. package/docs/user-guide/catalog/screen-facet-list.webp +0 -0
  943. package/docs/user-guide/catalog/screen-inventory.webp +0 -0
  944. package/docs/user-guide/customers/index.md +30 -0
  945. package/docs/user-guide/customers/screen-customer-group.webp +0 -0
  946. package/docs/user-guide/index.md +7 -0
  947. package/docs/user-guide/localization/index.md +42 -0
  948. package/docs/user-guide/localization/screen-ui-language.webp +0 -0
  949. package/docs/user-guide/orders/draft-orders.md +28 -0
  950. package/docs/user-guide/orders/order-state-diagram-for-admin.png +0 -0
  951. package/docs/user-guide/orders/orders.md +65 -0
  952. package/docs/user-guide/orders/screen-fulfillment-shipped.webp +0 -0
  953. package/docs/user-guide/orders/screen-fulfillment.webp +0 -0
  954. package/docs/user-guide/orders/screen-modification.webp +0 -0
  955. package/docs/user-guide/orders/screen-modify-button.webp +0 -0
  956. package/docs/user-guide/orders/screen-refund-button.webp +0 -0
  957. package/docs/user-guide/orders/screen-settle-payment.webp +0 -0
  958. package/docs/user-guide/promotions/index.md +44 -0
  959. package/docs/user-guide/settings/administrators-roles.md +34 -0
  960. package/docs/user-guide/settings/channels.md +18 -0
  961. package/docs/user-guide/settings/countries-zones.md +12 -0
  962. package/docs/user-guide/settings/global-settings.md +12 -0
  963. package/docs/user-guide/settings/payment-methods.md +32 -0
  964. package/docs/user-guide/settings/screen-shipping-test.webp +0 -0
  965. package/docs/user-guide/settings/screen-translations.webp +0 -0
  966. package/docs/user-guide/settings/shipping-methods.md +55 -0
  967. package/docs/user-guide/settings/taxes.md +32 -0
  968. package/package.json +32 -0
@@ -0,0 +1,1902 @@
1
+ ---
2
+ title: Migrating from Admin UI
3
+ sidebar_position: 1
4
+ ---
5
+
6
+ # Migrating from Admin UI
7
+
8
+ If you have existing extensions to the legacy Angular-based Admin UI, you will want to migrate to the new Dashboard to enjoy
9
+ an improved developer experience, many more customization options, and ongoing support from the Vendure team.
10
+
11
+ :::warning
12
+ The Angular Admin UI will not be maintained after **July 2026**. Until then, we will continue patching critical bugs and security issues.
13
+ Community contributions will always be merged and released.
14
+ :::
15
+
16
+ ## Running In Parallel
17
+
18
+ A recommended approach to migrating is to run both the Admin UI _and_ the new Dashboard in parallel. This allows you to start building
19
+ new features right away with the new Dashboard while maintaining access to existing features that have not yet been migrated.
20
+
21
+ To do so, follow the instructions to [set up the Dashboard](/guides/extending-the-dashboard/getting-started/#installation--setup).
22
+ Both plugins can now be used simultaneously without any special configuration.
23
+
24
+ ## AI-Assisted Migration
25
+
26
+ We highly recommend using AI tools such as Claude Code, Codex etc to assist with migrations from the legacy Angular-based UI extensions
27
+ to the new React-based Dashboard.
28
+
29
+ :::info
30
+ The results of AI-assisted migration are heavily dependent on the model that you use. We tested with
31
+ Claude Code using Sonnet 4.5 & Codex using gpt-5-codex
32
+ :::
33
+
34
+ In our testing, we were able to perform complete migrations quickly using the following approach:
35
+
36
+ 1. Use the provided prompt or Claude skill and specify which plugin you wish to migrate (do 1 at a time)
37
+ 2. Allow the AI tool to complete the migration
38
+ 3. Manually clean up & fix any issues that remain
39
+
40
+ Using this approach we were able to migrate complete plugins involving list/details views, widgets, and custom field components
41
+ in around 20-30 minutes.
42
+
43
+ ### Full Prompt
44
+
45
+ Give a prompt like this to your AI assistant and make sure to specify the plugin by path, i.e.:
46
+
47
+ ```
48
+ Migrate the plugin at @src/plugins/my-plugin/
49
+ to use the new dashboard.
50
+ ```
51
+
52
+ Then paste the following prompt in full:
53
+
54
+ <div style={{ width: '100%', height: '500px', overflow: 'auto', marginBottom: '20px' }}>
55
+
56
+ <!-- Note: the following code block should not be edited. It is auto-generated from the files in the
57
+ `.claude/skills/vendure-dashboard-migration` dir, by running the npm script `generate-migration-prompt` from
58
+ the `./docs` dir. -->
59
+ ````md
60
+ ## Instructions
61
+
62
+ 1. If not explicitly stated by the user, find out which plugin they want to migrate.
63
+ 2. Read and understand the overall rules for migration
64
+ - the "General" section below
65
+ - the "Common Tasks" section below
66
+ 3. Check the tsconfig setup <tsconfig-setup>. This may or may not already be set up.
67
+ - the "TSConfig setup" section below
68
+ 4. Identify each part of the Admin UI extensions that needs to be
69
+ migrated, and use the data from the appropriate sections to guide
70
+ the migration:
71
+ - the "Forms" section below
72
+ - the "Custom Field Inputs" section below
73
+ - the "List Pages" section below
74
+ - the "Detail Pages" section below
75
+ - the "Adding Nav Menu Items" section below
76
+ - the "Action Bar Items" section below
77
+ - the "Custom Detail Components" section below
78
+ - the "Page Tabs" section below
79
+ - the "Widgets" section below
80
+ 5. Ensure you have followed the instructions marked "Important" for each section
81
+
82
+ ## General
83
+
84
+ - For short we use "old" to refer to code written for the Angular Admin UI, and "new" for the React Dashboard
85
+ - old code is usually in a plugin's "ui" dir
86
+ - new code should be in a plugin's "dashboard" dir
87
+ - new code imports all components from `@vendure/dashboard`. It can also import the following as needed:
88
+ - hooks or anything else needed from `react`
89
+ - hooks etc from `@tanstack/react-query`
90
+ - `Link`, `useNavigate` etc from `@tanstack/react-router`
91
+ - `useForm` etc from `react-hook-form`
92
+ - `toast` from `sonner`
93
+ - icons from `lucide-react`
94
+ - for i18n: `Trans`, `useLingui` from `@lingui/react/macro`
95
+ - Default to the style conventions of the current project as much as possible (single vs double quotes,
96
+ indent size etc)
97
+
98
+
99
+ ## Directory Structure
100
+ Given as an example - projects may differ in conventions
101
+
102
+ ### Old
103
+
104
+ ```
105
+ - /path/to/plugin
106
+ - /ui
107
+ - providers.ts
108
+ - routes.ts
109
+ - /components
110
+ - /example
111
+ - example.component.ts
112
+ - example.component.html
113
+ - example.component.scss
114
+ - example.graphql.ts
115
+ ```
116
+
117
+
118
+ ### New
119
+
120
+ ```
121
+ - /path/to/plugin
122
+ - /dashboard
123
+ - index.tsx
124
+ - /components
125
+ - example.tsx
126
+ ```
127
+
128
+ ## Registering extensions
129
+
130
+ ### Old
131
+
132
+ ```ts title="src/plugins/my-plugin/my.plugin.ts"
133
+ import * as path from 'path';
134
+ import { VendurePlugin } from '@vendure/core';
135
+ import { AdminUiExtension } from '@vendure/ui-devkit/compiler';
136
+
137
+ @VendurePlugin({
138
+ // ...
139
+ })
140
+ export class MyPlugin {
141
+ static ui: AdminUiExtension = {
142
+ id: 'my-plugin-ui',
143
+ extensionPath: path.join(__dirname, 'ui'),
144
+ routes: [{ route: 'my-plugin', filePath: 'routes.ts' }],
145
+ providers: ['providers.ts'],
146
+ };
147
+ }
148
+ ```
149
+
150
+ ### New
151
+
152
+ ```ts title="src/plugins/my-plugin/my.plugin.ts"
153
+ import { VendurePlugin } from '@vendure/core';
154
+
155
+ @VendurePlugin({
156
+ // ...
157
+ // Note that this needs to match the relative path to the
158
+ // index.tsx file from the plugin file
159
+ dashboard: '../dashboard/index.tsx',
160
+ })
161
+ export class MyPlugin {
162
+ // Do not remove any existing AdminUiExtension def
163
+ // to preserve backward compatibility
164
+ static ui: AdminUiExtension = { /* ... */ }
165
+ }
166
+ ```
167
+
168
+ Important:
169
+ - Ensure the `dashboard` path is correct relative to the locations of the plugin.ts file and the index.ts file
170
+
171
+ ## Styling
172
+
173
+ ### Old
174
+
175
+ custom design system based on Clarity UI
176
+
177
+ ```html
178
+ <button class="button primary">Primary</button>
179
+ <button class="button secondary">Secondary</button>
180
+ <button class="button success">Success</button>
181
+ <button class="button warning">Warning</button>
182
+ <button class="button danger">Danger</button>
183
+
184
+ <button class="button-ghost">Ghost</button>
185
+
186
+ <a class="button-ghost" [routerLink]="['/extensions/my-plugin/my-custom-route']">
187
+ <clr-icon shape="arrow" dir="right"></clr-icon>
188
+ John Smith
189
+ </a>
190
+
191
+ <button class="button-small">Small</button>
192
+
193
+ <button class="button-small">
194
+ <clr-icon shape="layers"></clr-icon>
195
+ Assign to channel
196
+ </button>
197
+
198
+ <clr-icon shape="star" size="8"></clr-icon>
199
+
200
+ <img [src]="product.featuredAsset?.preview + '?preset=small'" alt="Product preview" />
201
+ ```
202
+
203
+ ### New
204
+
205
+ tailwind + shadcn/ui. Shadcn components import from `@vendure/dashboard`
206
+
207
+ ```tsx
208
+ import { Button, DetailPageButton, VendureImage } from '@vendure/dashboard';
209
+ import { Star } from 'lucide-react';
210
+
211
+ export function MyComponent() {
212
+ // non-exhaustive - all standard Shadcn props are available
213
+ return (
214
+ <Button variant="default">Primary</Button>
215
+ <Button variant="secondary">Secondary</Button>
216
+ <Button variant="outline">Outline</Button>
217
+ <Button variant="destructive">Danger</Button>
218
+ <Button variant="ghost">Ghost</Button>
219
+
220
+ <DetailPageButton id="123" label="John Smith" />
221
+ <DetailPageButton href="/affiliates/my-custom-route" label="John Smith" />
222
+
223
+ <Star />
224
+
225
+ <VendureImage
226
+ src={entity.product.featuredAsset}
227
+ alt={entity.product.name}
228
+ preset='small'
229
+ />
230
+ )
231
+ }
232
+ ```
233
+
234
+ Important:
235
+
236
+ - When using `Badge`, prefer variant="secondary" unless especially important data
237
+ - Where possible avoid specific tailwind colours like `text-blue-600`. Instead use (where possible)
238
+ the Shadcn theme colours, eg:
239
+ ```
240
+ --color-background
241
+ --color-foreground
242
+ --color-primary
243
+ --color-primary-foreground
244
+ --color-secondary
245
+ --color-secondary-foreground
246
+ --color-muted
247
+ --color-muted-foreground
248
+ --color-accent
249
+ --color-accent-foreground
250
+ --color-destructive
251
+ --color-destructive-foreground
252
+ --color-success
253
+ --color-success-foreground
254
+ ```
255
+ - Buttons which link to detail pages should use `DetailPageButton`
256
+
257
+ ## Data access
258
+
259
+ ### Old
260
+
261
+ ```ts
262
+ import { DataService } from '@vendure/admin-ui/core';
263
+ import { graphql } from "../gql";
264
+
265
+ export const GET_CUSTOMER_NAME = graphql(`
266
+ query GetCustomerName($id: ID!) {
267
+ customer(id: $id) {
268
+ id
269
+ firstName
270
+ lastName
271
+ addresses {
272
+ ...AddressFragment
273
+ }
274
+ }
275
+ }
276
+ `);
277
+
278
+ this.dataService.query(GET_CUSTOMER_NAME, {
279
+ id: customerId,
280
+ }),
281
+ ```
282
+
283
+ ### New
284
+
285
+ ```ts
286
+ import { useQuery } from '@tanstack/react-query';
287
+ import { api } from '@vendure/dashboard';
288
+ import { graphql } from '@/gql';
289
+
290
+ const addressFragment = graphql(`
291
+ # ...
292
+ `);
293
+
294
+ const getCustomerNameDocument = graphql(`
295
+ query GetCustomerName($id: ID!) {
296
+ customer(id: $id) {
297
+ id
298
+ firstName
299
+ lastName
300
+ addresses {
301
+ ...AddressFragment
302
+ }
303
+ }
304
+ }
305
+ `, [addressFragment]); // Fragments MUST be explicitly referenced
306
+
307
+ const { data, isLoading, error } = useQuery({
308
+ queryKey: ['customer-name', customerId],
309
+ queryFn: () => api.query(getCustomerNameDocument, { id: customerId }),
310
+ });
311
+ ```
312
+
313
+ Note on graphql fragments: if common fragments are used across files, you may need
314
+ to extract them into a common-fragments.graphql.ts file, because with gql.tada they
315
+ *must* be explicitly referenced in every document that uses them.
316
+
317
+ ## Common Tasks
318
+
319
+ ### Formatting Dates, Currencies, and Numbers
320
+
321
+ ```tsx
322
+ import {useLocalFormat} from '@vendure/dashboard';
323
+ // ...
324
+ // Intl API formatting tools
325
+ const {
326
+ formatCurrency,
327
+ formatNumber,
328
+ formatDate,
329
+ formatRelativeDate,
330
+ formatLanguageName,
331
+ formatRegionName,
332
+ formatCurrencyName,
333
+ toMajorUnits,
334
+ toMinorUnits,
335
+ } = useLocalFormat();
336
+
337
+ formatCurrency(value: number, currency: string, precision?: number)
338
+ formatCurrencyName(currencyCode: string, display: 'full' | 'symbol' | 'name' = 'full')
339
+ formatNumber(value: number) // human-readable
340
+ formatDate(value: string | Date, options?: Intl.DateTimeFormatOptions)
341
+ formatRelativeDate(value: string | Date, options?: Intl.RelativeTimeFormatOptions)
342
+ ```
343
+
344
+ ### Links
345
+
346
+ Example link destinations:
347
+ - Customer detail | <Link to="/customers/$id" params={{ id }}>text</Link>
348
+ - Customer list | <Link to="/customers">text</Link>
349
+ - Order detail | <Link to="/orders/$id" params={{ id }}>text</Link>
350
+
351
+ Important: when linking to detail pages, prefer the `DetailPageButton`. If not in a table column,
352
+ add `className='border'`.
353
+
354
+ ## TSConfig setup
355
+
356
+ If not already set up, we need to make sure we have configured tsconfig with:
357
+
358
+ 1. jsx support. Usually create `tsconfig.dashboard.json` like this:
359
+ ```json
360
+ {
361
+ "extends": "./tsconfig.json",
362
+ "compilerOptions": {
363
+ "composite": true,
364
+ "jsx": "react-jsx"
365
+ },
366
+ "include": [
367
+ "src/dashboard/**/*.ts",
368
+ "src/dashboard/**/*.tsx"
369
+ ]
370
+ }
371
+ ```
372
+ then reference it from the appropriate tsconfig.json
373
+ ```
374
+ {
375
+ // ...etc
376
+ "references": [
377
+ {
378
+ "path": "./tsconfig.dashboard.json"
379
+ },
380
+ ]
381
+ }
382
+ ```
383
+ This may already be set up (check this). In an Nx-like monorepo
384
+ where each plugin is a separate project, this will need to be done
385
+ per-plugin.
386
+ 2. Path mapping.
387
+ ```json
388
+ "paths": {
389
+ // Import alias for the GraphQL types, this needs to point to
390
+ // the location specified in the vite.config.mts file as `gqlOutputPath`
391
+ // so will vary depending on project structure
392
+ "@/gql": ["./apps/server/src/gql/graphql.ts"],
393
+ // This line allows TypeScript to properly resolve internal
394
+ // Vendure Dashboard imports, which is necessary for
395
+ // type safety in your dashboard extensions.
396
+ // This path assumes a root-level tsconfig.json file.
397
+ // You may need to adjust it if your project structure is different.
398
+ "@/vdb/*": [
399
+ "./node_modules/@vendure/dashboard/src/lib/*"
400
+ }
401
+ ```
402
+ In an Nx-like monorepo, this would be added to the tsconfig.base.json or
403
+ equivalent.
404
+
405
+ ## Forms
406
+
407
+ ### Old (Angular)
408
+ ```html
409
+ <div class="form-grid">
410
+ <vdr-form-field label="Page title">
411
+ <input type="text" />
412
+ </vdr-form-field>
413
+ <vdr-form-field label="Select input">
414
+ <select>
415
+ <option>Option 1</option>
416
+ <option>Option 2</option>
417
+ </select>
418
+ </vdr-form-field>
419
+ <vdr-form-field label="Checkbox input">
420
+ <input type="checkbox" />
421
+ </vdr-form-field>
422
+ <vdr-form-field label="Textarea input">
423
+ <textarea></textarea>
424
+ </vdr-form-field>
425
+ <vdr-form-field label="Invalid with error">
426
+ <input type="text" [formControl]="invalidFormControl" />
427
+ </vdr-form-field>
428
+ <vdr-rich-text-editor
429
+ class="form-grid-span"
430
+ label="Description"
431
+ ></vdr-rich-text-editor>
432
+ </div>
433
+ ```
434
+
435
+ ### New (React Dashboard)
436
+ ```tsx
437
+ <PageBlock column="main" blockId="main-form">
438
+ <DetailFormGrid>
439
+ <FormFieldWrapper
440
+ control={form.control}
441
+ name="title"
442
+ label="Title"
443
+ render={({ field }) => <Input {...field} />}
444
+ />
445
+ <FormFieldWrapper
446
+ control={form.control}
447
+ name="slug"
448
+ label="Slug"
449
+ render={({ field }) => <Input {...field} />}
450
+ />
451
+ </DetailFormGrid>
452
+ <div className="space-y-6">
453
+ <FormFieldWrapper
454
+ control={form.control}
455
+ name="body"
456
+ label="Content"
457
+ render={({ field }) => (
458
+ <RichTextInput value={field.value ?? ''} onChange={field.onChange} />
459
+ )}
460
+ />
461
+ </div>
462
+ </PageBlock>;
463
+ ```
464
+
465
+ ## Custom Field Inputs
466
+
467
+ ### Old (Angular)
468
+
469
+ ```ts title="src/plugins/common/ui/components/slider-form-input/slider-form-input.component.ts"
470
+ import { Component } from '@angular/core';
471
+ import { FormControl } from '@angular/forms';
472
+ import { IntCustomFieldConfig, SharedModule, FormInputComponent } from '@vendure/admin-ui/core';
473
+
474
+ @Component({
475
+ template: `
476
+ <input
477
+ type="range"
478
+ [min]="config.min || 0"
479
+ [max]="config.max || 100"
480
+ [formControl]="formControl" />
481
+ {{ formControl.value }}
482
+ `,
483
+ standalone: true,
484
+ imports: [SharedModule],
485
+ })
486
+ export class SliderControlComponent implements FormInputComponent<IntCustomFieldConfig> {
487
+ readonly: boolean;
488
+ config: IntCustomFieldConfig;
489
+ formControl: FormControl;
490
+ }
491
+ ```
492
+
493
+ ```ts title="src/plugins/common/ui/providers.ts"
494
+ import { registerFormInputComponent } from '@vendure/admin-ui/core';
495
+ import { SliderControlComponent } from './components/slider-form-input/slider-form-input.component';
496
+
497
+ export default [
498
+ registerFormInputComponent('slider-form-input', SliderControlComponent),
499
+ ];
500
+ ```
501
+
502
+ ### New (React Dashboard)
503
+
504
+ ```tsx title="src/plugins/my-plugin/dashboard/components/color-picker.tsx"
505
+ import { Button, Card, CardContent, cn, DashboardFormComponent, Input } from '@vendure/dashboard';
506
+ import { useState } from 'react';
507
+ import { useFormContext } from 'react-hook-form';
508
+
509
+ // By typing your component as DashboardFormComponent, the props will be correctly typed
510
+ export const ColorPickerComponent: DashboardFormComponent = ({ value, onChange, name }) => {
511
+ const [isOpen, setIsOpen] = useState(false);
512
+
513
+ const { getFieldState } = useFormContext();
514
+ const error = getFieldState(name).error;
515
+ const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57', '#FF9FF3', '#54A0FF', '#5F27CD'];
516
+
517
+ return (
518
+ <div className="space-y-2">
519
+ <div className="flex items-center space-x-2">
520
+ <Button
521
+ type="button"
522
+ variant="outline"
523
+ size="icon"
524
+ className={cn('w-8 h-8 border-2 border-gray-300 p-0', error && 'border-red-500')}
525
+ style={{ backgroundColor: error ? 'transparent' : value || '#ffffff' }}
526
+ onClick={() => setIsOpen(!isOpen)}
527
+ />
528
+ <Input value={value || ''} onChange={e => onChange(e.target.value)} placeholder="#ffffff" />
529
+ </div>
530
+
531
+ {isOpen && (
532
+ <Card>
533
+ <CardContent className="grid grid-cols-4 gap-2 p-2">
534
+ {colors.map(color => (
535
+ <Button
536
+ key={color}
537
+ type="button"
538
+ variant="outline"
539
+ size="icon"
540
+ className="w-8 h-8 border-2 border-gray-300 hover:border-gray-500 p-0"
541
+ style={{ backgroundColor: color }}
542
+ onClick={() => {
543
+ onChange(color);
544
+ setIsOpen(false);
545
+ }}
546
+ />
547
+ ))}
548
+ </CardContent>
549
+ </Card>
550
+ )}
551
+ </div>
552
+ );
553
+ };
554
+ ```
555
+
556
+ ```tsx title="src/plugins/my-plugin/dashboard/index.tsx"
557
+ import { defineDashboardExtension } from '@vendure/dashboard';
558
+ import { ColorPickerComponent } from './components/color-picker';
559
+
560
+ defineDashboardExtension({
561
+ customFormComponents: {
562
+ // Custom field components for custom fields
563
+ customFields: [
564
+ {
565
+ // The "id" is a global identifier for this custom component. We will
566
+ // reference it in the next step.
567
+ id: 'color-picker',
568
+ component: ColorPickerComponent,
569
+ },
570
+ ],
571
+ },
572
+ // ... other extension properties
573
+ });
574
+ ```
575
+
576
+ ## List Pages
577
+
578
+ ### Old (Angular)
579
+ ```ts
580
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
581
+ import { TypedBaseListComponent, SharedModule } from '@vendure/admin-ui/core';
582
+ // This is the TypedDocumentNode generated by GraphQL Code Generator
583
+ import { graphql } from '../../gql';
584
+
585
+ const getReviewListDocument = graphql(`
586
+ query GetReviewList($options: ReviewListOptions) {
587
+ reviews(options: $options) {
588
+ items {
589
+ id
590
+ createdAt
591
+ updatedAt
592
+ title
593
+ rating
594
+ text
595
+ authorName
596
+ productId
597
+ }
598
+ totalItems
599
+ }
600
+ }
601
+ `);
602
+
603
+ @Component({
604
+ selector: 'review-list',
605
+ templateUrl: './review-list.component.html',
606
+ styleUrls: ['./review-list.component.scss'],
607
+ changeDetection: ChangeDetectionStrategy.OnPush,
608
+ standalone: true,
609
+ imports: [SharedModule],
610
+ })
611
+ export class ReviewListComponent extends TypedBaseListComponent<typeof getReviewListDocument, 'reviews'> {
612
+
613
+ // Here we set up the filters that will be available
614
+ // to use in the data table
615
+ readonly filters = this.createFilterCollection()
616
+ .addIdFilter()
617
+ .addDateFilters()
618
+ .addFilter({
619
+ name: 'title',
620
+ type: {kind: 'text'},
621
+ label: 'Title',
622
+ filterField: 'title',
623
+ })
624
+ .addFilter({
625
+ name: 'rating',
626
+ type: {kind: 'number'},
627
+ label: 'Rating',
628
+ filterField: 'rating',
629
+ })
630
+ .addFilter({
631
+ name: 'authorName',
632
+ type: {kind: 'text'},
633
+ label: 'Author',
634
+ filterField: 'authorName',
635
+ })
636
+ .connectToRoute(this.route);
637
+
638
+ // Here we set up the sorting options that will be available
639
+ // to use in the data table
640
+ readonly sorts = this.createSortCollection()
641
+ .defaultSort('createdAt', 'DESC')
642
+ .addSort({name: 'createdAt'})
643
+ .addSort({name: 'updatedAt'})
644
+ .addSort({name: 'title'})
645
+ .addSort({name: 'rating'})
646
+ .addSort({name: 'authorName'})
647
+ .connectToRoute(this.route);
648
+
649
+ constructor() {
650
+ super();
651
+ super.configure({
652
+ document: getReviewListDocument,
653
+ getItems: data => data.reviews,
654
+ setVariables: (skip, take) => ({
655
+ options: {
656
+ skip,
657
+ take,
658
+ filter: {
659
+ title: {
660
+ contains: this.searchTermControl.value,
661
+ },
662
+ ...this.filters.createFilterInput(),
663
+ },
664
+ sort: this.sorts.createSortInput(),
665
+ },
666
+ }),
667
+ refreshListOnChanges: [this.filters.valueChanges, this.sorts.valueChanges],
668
+ });
669
+ }
670
+ }
671
+ ```
672
+
673
+ ```html
674
+ <!-- optional if you want some buttons at the top -->
675
+ <vdr-page-block>
676
+ <vdr-action-bar>
677
+ <vdr-ab-left></vdr-ab-left>
678
+ <vdr-ab-right>
679
+ <a class="btn btn-primary" *vdrIfPermissions="['CreateReview']" [routerLink]="['./', 'create']">
680
+ <clr-icon shape="plus"></clr-icon>
681
+ Create a review
682
+ </a>
683
+ </vdr-ab-right>
684
+ </vdr-action-bar>
685
+ </vdr-page-block>
686
+
687
+ <!-- The data table -->
688
+ <vdr-data-table-2
689
+ id="review-list"
690
+ [items]="items$ | async"
691
+ [itemsPerPage]="itemsPerPage$ | async"
692
+ [totalItems]="totalItems$ | async"
693
+ [currentPage]="currentPage$ | async"
694
+ [filters]="filters"
695
+ (pageChange)="setPageNumber($event)"
696
+ (itemsPerPageChange)="setItemsPerPage($event)"
697
+ >
698
+ <!-- optional if you want to support bulk actions -->
699
+ <vdr-bulk-action-menu
700
+ locationId="review-list"
701
+ [hostComponent]="this"
702
+ [selectionManager]="selectionManager"
703
+ />
704
+
705
+ <!-- Adds a search bar -->
706
+ <vdr-dt2-search
707
+ [searchTermControl]="searchTermControl"
708
+ searchTermPlaceholder="Filter by title"
709
+ />
710
+
711
+ <!-- Here we define all the available columns -->
712
+ <vdr-dt2-column id="id" [heading]="'common.id' | translate" [hiddenByDefault]="true">
713
+ <ng-template let-review="item">
714
+ {{ review.id }}
715
+ </ng-template>
716
+ </vdr-dt2-column>
717
+ <vdr-dt2-column
718
+ id="created-at"
719
+ [heading]="'common.created-at' | translate"
720
+ [hiddenByDefault]="true"
721
+ [sort]="sorts.get('createdAt')"
722
+ >
723
+ <ng-template let-review="item">
724
+ {{ review.createdAt | localeDate : 'short' }}
725
+ </ng-template>
726
+ </vdr-dt2-column>
727
+ <vdr-dt2-column
728
+ id="updated-at"
729
+ [heading]="'common.updated-at' | translate"
730
+ [hiddenByDefault]="true"
731
+ [sort]="sorts.get('updatedAt')"
732
+ >
733
+ <ng-template let-review="item">
734
+ {{ review.updatedAt | localeDate : 'short' }}
735
+ </ng-template>
736
+ </vdr-dt2-column>
737
+ <vdr-dt2-column id="title" heading="Title" [optional]="false" [sort]="sorts.get('title')">
738
+ <ng-template let-review="item">
739
+ <a class="button-ghost" [routerLink]="['./', review.id]"
740
+ ><span>{{ review.title }}</span>
741
+ <clr-icon shape="arrow right"></clr-icon>
742
+ </a>
743
+ </ng-template>
744
+ </vdr-dt2-column>
745
+ <vdr-dt2-column id="rating" heading="Rating" [sort]="sorts.get('rating')">
746
+ <ng-template let-review="item"><my-star-rating-component [rating]="review.rating" /></ng-template>
747
+ </vdr-dt2-column>
748
+ <vdr-dt2-column id="author" heading="Author" [sort]="sorts.get('authorName')">
749
+ <ng-template let-review="item">{{ review.authorName }}</ng-template>
750
+ </vdr-dt2-column>
751
+ </vdr-data-table-2>
752
+ ```
753
+
754
+ ```ts
755
+ import { registerRouteComponent } from '@vendure/admin-ui/core';
756
+
757
+ import { ReviewListComponent } from './components/review-list/review-list.component';
758
+
759
+ export default [
760
+ registerRouteComponent({
761
+ path: '',
762
+ component: ReviewListComponent,
763
+ breadcrumb: 'Product reviews',
764
+ }),
765
+ ]
766
+ ```
767
+
768
+ ### New (React Dashboard)
769
+
770
+ ```tsx
771
+ import {
772
+ Button,
773
+ DashboardRouteDefinition,
774
+ ListPage,
775
+ PageActionBarRight,
776
+ DetailPageButton,
777
+ } from '@vendure/dashboard';
778
+ import { Link } from '@tanstack/react-router';
779
+ import { PlusIcon } from 'lucide-react';
780
+
781
+ // This function is generated for you by the `vendureDashboardPlugin` in your Vite config.
782
+ // It uses gql-tada to generate TypeScript types which give you type safety as you write
783
+ // your queries and mutations.
784
+ import { graphql } from '@/gql';
785
+
786
+ // The fields you select here will be automatically used to generate the appropriate columns in the
787
+ // data table below.
788
+ const getArticleList = graphql(`
789
+ query GetArticles($options: ArticleListOptions) {
790
+ articles(options: $options) {
791
+ items {
792
+ id
793
+ createdAt
794
+ updatedAt
795
+ isPublished
796
+ title
797
+ slug
798
+ body
799
+ customFields
800
+ }
801
+ totalItems
802
+ }
803
+ }
804
+ `);
805
+
806
+ const deleteArticleDocument = graphql(`
807
+ mutation DeleteArticle($id: ID!) {
808
+ deleteArticle(id: $id) {
809
+ result
810
+ }
811
+ }
812
+ `);
813
+
814
+ export const articleList: DashboardRouteDefinition = {
815
+ navMenuItem: {
816
+ sectionId: 'catalog',
817
+ id: 'articles',
818
+ url: '/articles',
819
+ title: 'CMS Articles',
820
+ },
821
+ path: '/articles',
822
+ loader: () => ({
823
+ breadcrumb: 'Articles',
824
+ }),
825
+ component: route => (
826
+ <ListPage
827
+ pageId="article-list"
828
+ title="Articles"
829
+ listQuery={getArticleList}
830
+ deleteMutation={deleteArticleDocument}
831
+ route={route}
832
+ customizeColumns={{
833
+ title: {
834
+ cell: ({ row }) => {
835
+ const post = row.original;
836
+ return <DetailPageButton id={post.id} label={post.title} />;
837
+ },
838
+ },
839
+ }}
840
+ defaultVisibility={{
841
+ type: true,
842
+ summary: true,
843
+ state: true,
844
+ rating: true,
845
+ authorName: true,
846
+ authorLocation: true,
847
+ }}
848
+ defaultColumnOrder={[
849
+ 'type',
850
+ 'summary',
851
+ 'authorName',
852
+ 'authorLocation',
853
+ 'rating',
854
+ ]}
855
+ >
856
+ <PageActionBarRight>
857
+ <Button asChild>
858
+ <Link to="./new">
859
+ <PlusIcon className="mr-2 h-4 w-4" />
860
+ New article
861
+ </Link>
862
+ </Button>
863
+ </PageActionBarRight>
864
+ </ListPage>
865
+ ),
866
+ };
867
+ ```
868
+
869
+ Important:
870
+ - When using `defaultVisibility`, specify the specific visible ones with `true`. *Do not* mix
871
+ true and false values. It is implicit that any not specified will default to `false`.
872
+ - The `id`, `createdAt` and `updatedAt` never need to be specified in `customizeColumns`, defaultVisibility` or `defaultColumnOrder`.
873
+ They are handled correctly by default.
874
+ - By default the DataTable will handle column names based on the field name,
875
+ e.g. `authorName` -> `Author Name`, `rating` -> `Rating`, so an explicit cell header is
876
+ not needed unless the column header title must significantly differ from the field name.
877
+ - If a custom `cell` function needs to access fields _other_ than the one being rendered,
878
+ those other fields *must* be declared as dependencies:
879
+ ```tsx
880
+ customizeColumns={{
881
+ name: {
882
+ // Note, we DO NOT need to declare "name" as a dependency here,
883
+ // since we are handling the `name` column already.
884
+ meta: { dependencies: ['reviewCount'] },
885
+ cell: ({ row }) => {
886
+ const { name, reviewCount } = row.original;
887
+ return <Badge variant="outline">{name} ({reviewCount})</Badge>
888
+ },
889
+ },
890
+ }}
891
+ ```
892
+
893
+ ## Detail Pages
894
+
895
+ ### Old (Angular)
896
+ ```ts
897
+ import { ResultOf } from '@graphql-typed-document-node/core';
898
+ import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from '@angular/core';
899
+ import { FormBuilder } from '@angular/forms';
900
+ import { TypedBaseDetailComponent, LanguageCode, NotificationService, SharedModule } from '@vendure/admin-ui/core';
901
+
902
+ // This is the TypedDocumentNode & type generated by GraphQL Code Generator
903
+ import { graphql } from '../../gql';
904
+
905
+ export const reviewDetailFragment = graphql(`
906
+ fragment ReviewDetail on ProductReview {
907
+ id
908
+ createdAt
909
+ updatedAt
910
+ title
911
+ rating
912
+ text
913
+ authorName
914
+ productId
915
+ }
916
+ `);
917
+
918
+ export const getReviewDetailDocument = graphql(`
919
+ query GetReviewDetail($id: ID!) {
920
+ review(id: $id) {
921
+ ...ReviewDetail
922
+ }
923
+ }
924
+ `);
925
+
926
+ export const createReviewDocument = graphql(`
927
+ mutation CreateReview($input: CreateProductReviewInput!) {
928
+ createProductReview(input: $input) {
929
+ ...ReviewDetail
930
+ }
931
+ }
932
+ `);
933
+
934
+ export const updateReviewDocument = graphql(`
935
+ mutation UpdateReview($input: UpdateProductReviewInput!) {
936
+ updateProductReview(input: $input) {
937
+ ...ReviewDetail
938
+ }
939
+ }
940
+ `);
941
+
942
+ @Component({
943
+ selector: 'review-detail',
944
+ templateUrl: './review-detail.component.html',
945
+ styleUrls: ['./review-detail.component.scss'],
946
+ changeDetection: ChangeDetectionStrategy.OnPush,
947
+ standalone: true,
948
+ imports: [SharedModule],
949
+ })
950
+ export class ReviewDetailComponent extends TypedBaseDetailComponent<typeof getReviewDetailDocument, 'review'> implements OnInit, OnDestroy {
951
+ detailForm = this.formBuilder.group({
952
+ title: [''],
953
+ rating: [1],
954
+ authorName: [''],
955
+ });
956
+
957
+ constructor(private formBuilder: FormBuilder, private notificationService: NotificationService) {
958
+ super();
959
+ }
960
+
961
+ ngOnInit() {
962
+ this.init();
963
+ }
964
+
965
+ ngOnDestroy() {
966
+ this.destroy();
967
+ }
968
+
969
+ create() {
970
+ const { title, rating, authorName } = this.detailForm.value;
971
+ if (!title || rating == null || !authorName) {
972
+ return;
973
+ }
974
+ this.dataService
975
+ .mutate(createReviewDocument, {
976
+ input: { title, rating, authorName },
977
+ })
978
+ .subscribe(({ createProductReview }) => {
979
+ if (createProductReview.id) {
980
+ this.notificationService.success('Review created');
981
+ this.router.navigate(['extensions', 'reviews', createProductReview.id]);
982
+ }
983
+ });
984
+ }
985
+
986
+ update() {
987
+ const { title, rating, authorName } = this.detailForm.value;
988
+ this.dataService
989
+ .mutate(updateReviewDocument, {
990
+ input: { id: this.id, title, rating, authorName },
991
+ })
992
+ .subscribe(() => {
993
+ this.notificationService.success('Review updated');
994
+ });
995
+ }
996
+
997
+ protected setFormValues(entity: NonNullable<ResultOf<typeof getReviewDetailDocument>['review']>, languageCode: LanguageCode): void {
998
+ this.detailForm.patchValue({
999
+ title: entity.name,
1000
+ rating: entity.rating,
1001
+ authorName: entity.authorName,
1002
+ productId: entity.productId,
1003
+ });
1004
+ }
1005
+ }
1006
+ ```
1007
+
1008
+ ```html
1009
+ <vdr-page-block>
1010
+ <vdr-action-bar>
1011
+ <vdr-ab-left></vdr-ab-left>
1012
+ <vdr-ab-right>
1013
+ <button
1014
+ class="button primary"
1015
+ *ngIf="isNew$ | async; else updateButton"
1016
+ (click)="create()"
1017
+ [disabled]="detailForm.pristine || detailForm.invalid"
1018
+ >
1019
+ {{ 'common.create' | translate }}
1020
+ </button>
1021
+ <ng-template #updateButton>
1022
+ <button
1023
+ class="btn btn-primary"
1024
+ (click)="update()"
1025
+ [disabled]="detailForm.pristine || detailForm.invalid"
1026
+ >
1027
+ {{ 'common.update' | translate }}
1028
+ </button>
1029
+ </ng-template>
1030
+ </vdr-ab-right>
1031
+ </vdr-action-bar>
1032
+ </vdr-page-block>
1033
+
1034
+ <form class="form" [formGroup]="detailForm">
1035
+ <vdr-page-detail-layout>
1036
+ <!-- The sidebar is used for displaying "metadata" type information about the entity -->
1037
+ <vdr-page-detail-sidebar>
1038
+ <vdr-card *ngIf="entity$ | async as entity">
1039
+ <vdr-page-entity-info [entity]="entity" />
1040
+ </vdr-card>
1041
+ </vdr-page-detail-sidebar>
1042
+
1043
+ <!-- The main content area is used for displaying the entity's fields -->
1044
+ <vdr-page-block>
1045
+ <!-- The vdr-card is the container for grouping items together on a page -->
1046
+ <!-- it can also take an optional [title] property to display a title -->
1047
+ <vdr-card>
1048
+ <!-- the form-grid class is used to lay out the form fields -->
1049
+ <div class="form-grid">
1050
+ <vdr-form-field label="Title" for="title">
1051
+ <input id="title" type="text" formControlName="title" />
1052
+ </vdr-form-field>
1053
+ <vdr-form-field label="Rating" for="rating">
1054
+ <input id="rating" type="number" min="1" max="5" formControlName="rating" />
1055
+ </vdr-form-field>
1056
+
1057
+ <!-- etc -->
1058
+ </div>
1059
+ </vdr-card>
1060
+ </vdr-page-block>
1061
+ </vdr-page-detail-layout>
1062
+ </form>
1063
+ ```
1064
+
1065
+ ```ts
1066
+ import { registerRouteComponent } from '@vendure/admin-ui/core';
1067
+
1068
+ import { ReviewDetailComponent, getReviewDetailDocument } from './components/review-detail/review-detail.component';
1069
+
1070
+ export default [
1071
+ registerRouteComponent({
1072
+ path: ':id',
1073
+ component: ReviewDetailComponent,
1074
+ query: getReviewDetailDocument,
1075
+ entityKey: 'productReview',
1076
+ getBreadcrumbs: entity => [
1077
+ {
1078
+ label: 'Product reviews',
1079
+ link: ['/extensions', 'product-reviews'],
1080
+ },
1081
+ {
1082
+ label: `#${entity?.id} (${entity?.product.name})`,
1083
+ link: [],
1084
+ },
1085
+ ],
1086
+ }),
1087
+ ]
1088
+ ```
1089
+
1090
+ ### New (React Dashboard)
1091
+
1092
+ ```tsx
1093
+ import {
1094
+ DashboardRouteDefinition,
1095
+ detailPageRouteLoader,
1096
+ useDetailPage,
1097
+ Page,
1098
+ PageTitle,
1099
+ PageActionBar,
1100
+ PageActionBarRight,
1101
+ PermissionGuard,
1102
+ Button,
1103
+ PageLayout,
1104
+ PageBlock,
1105
+ FormFieldWrapper,
1106
+ DetailFormGrid,
1107
+ Switch,
1108
+ Input,
1109
+ RichTextInput,
1110
+ CustomFieldsPageBlock,
1111
+ } from '@vendure/dashboard';
1112
+ import { AnyRoute, useNavigate } from '@tanstack/react-router';
1113
+ import { toast } from 'sonner';
1114
+
1115
+ import { graphql } from '@/gql';
1116
+
1117
+ const articleDetailDocument = graphql(`
1118
+ query GetArticleDetail($id: ID!) {
1119
+ article(id: $id) {
1120
+ id
1121
+ createdAt
1122
+ updatedAt
1123
+ isPublished
1124
+ title
1125
+ slug
1126
+ body
1127
+ customFields
1128
+ }
1129
+ }
1130
+ `);
1131
+
1132
+ const createArticleDocument = graphql(`
1133
+ mutation CreateArticle($input: CreateArticleInput!) {
1134
+ createArticle(input: $input) {
1135
+ id
1136
+ }
1137
+ }
1138
+ `);
1139
+
1140
+ const updateArticleDocument = graphql(`
1141
+ mutation UpdateArticle($input: UpdateArticleInput!) {
1142
+ updateArticle(input: $input) {
1143
+ id
1144
+ }
1145
+ }
1146
+ `);
1147
+
1148
+ export const articleDetail: DashboardRouteDefinition = {
1149
+ path: '/articles/$id',
1150
+ loader: detailPageRouteLoader({
1151
+ queryDocument: articleDetailDocument,
1152
+ breadcrumb: (isNew, entity) => [
1153
+ { path: '/articles', label: 'Articles' },
1154
+ isNew ? 'New article' : entity?.title,
1155
+ ],
1156
+ }),
1157
+ component: route => {
1158
+ return <ArticleDetailPage route={route} />;
1159
+ },
1160
+ };
1161
+
1162
+ function ArticleDetailPage({ route }: { route: AnyRoute }) {
1163
+ const params = route.useParams();
1164
+ const navigate = useNavigate();
1165
+ const creatingNewEntity = params.id === 'new';
1166
+
1167
+ const { form, submitHandler, entity, isPending, resetForm, refreshEntity } = useDetailPage({
1168
+ queryDocument: articleDetailDocument,
1169
+ createDocument: createArticleDocument,
1170
+ updateDocument: updateArticleDocument,
1171
+ setValuesForUpdate: article => {
1172
+ return {
1173
+ id: article?.id ?? '',
1174
+ isPublished: article?.isPublished ?? false,
1175
+ title: article?.title ?? '',
1176
+ slug: article?.slug ?? '',
1177
+ body: article?.body ?? '',
1178
+ };
1179
+ },
1180
+ params: { id: params.id },
1181
+ onSuccess: async data => {
1182
+ toast.success('Successfully updated article');
1183
+ resetForm();
1184
+ if (creatingNewEntity) {
1185
+ await navigate({ to: `../$id`, params: { id: data.id } });
1186
+ }
1187
+ },
1188
+ onError: err => {
1189
+ toast.error('Failed to update article', {
1190
+ description: err instanceof Error ? err.message : 'Unknown error',
1191
+ });
1192
+ },
1193
+ });
1194
+
1195
+ return (
1196
+ <Page pageId="article-detail" form={form} submitHandler={submitHandler}>
1197
+ <PageTitle>{creatingNewEntity ? 'New article' : (entity?.title ?? '')}</PageTitle>
1198
+ <PageActionBar>
1199
+ <PageActionBarRight>
1200
+ <PermissionGuard requires={['UpdateProduct', 'UpdateCatalog']}>
1201
+ <Button
1202
+ type="submit"
1203
+ disabled={!form.formState.isDirty || !form.formState.isValid || isPending}
1204
+ >
1205
+ Update
1206
+ </Button>
1207
+ </PermissionGuard>
1208
+ </PageActionBarRight>
1209
+ </PageActionBar>
1210
+ <PageLayout>
1211
+ <PageBlock column="side" blockId="publish-status" title="Status" description="Current status of this article">
1212
+ <FormFieldWrapper
1213
+ control={form.control}
1214
+ name="isPublished"
1215
+ label="Is Published"
1216
+ render={({ field }) => (
1217
+ <Switch checked={field.value} onCheckedChange={field.onChange} />
1218
+ )}
1219
+ />
1220
+ </PageBlock>
1221
+ <PageBlock column="main" blockId="main-form">
1222
+ <DetailFormGrid>
1223
+ <FormFieldWrapper
1224
+ control={form.control}
1225
+ name="title"
1226
+ label="Title"
1227
+ render={({ field }) => <Input {...field} />}
1228
+ />
1229
+ <FormFieldWrapper
1230
+ control={form.control}
1231
+ name="slug"
1232
+ label="Slug"
1233
+ render={({ field }) => <Input {...field} />}
1234
+ />
1235
+ </DetailFormGrid>
1236
+ <div className="space-y-6">
1237
+ <FormFieldWrapper
1238
+ control={form.control}
1239
+ name="body"
1240
+ label="Content"
1241
+ render={({ field }) => (
1242
+ <RichTextInput value={field.value ?? ''} onChange={field.onChange} />
1243
+ )}
1244
+ />
1245
+ </div>
1246
+ </PageBlock>
1247
+ <CustomFieldsPageBlock column="main" entityType="Article" control={form.control} />
1248
+ </PageLayout>
1249
+ </Page>
1250
+ );
1251
+ }
1252
+ ```
1253
+
1254
+ Important:
1255
+ - The PageBlock component should *never* contain any Card-like component, because it already
1256
+ renders like a card.
1257
+ - Use `refreshEntity` to trigger a manual reload of the entity data (e.g. after a mutation
1258
+ succeeds)
1259
+ - The `DetailFormGrid` has a built-in `mb-6`, but for components not wrapped in this,
1260
+ manually ensure there is a y gap of 6 (e.g. wrap in `<div className="space-y-6">`)
1261
+
1262
+ ## Adding Nav Menu Items
1263
+
1264
+ ### Old (Angular)
1265
+ ```ts
1266
+ import { addNavMenuSection } from '@vendure/admin-ui/core';
1267
+
1268
+ export default [
1269
+ addNavMenuSection({
1270
+ id: 'greeter',
1271
+ label: 'My Extensions',
1272
+ items: [{
1273
+ id: 'greeter',
1274
+ label: 'Greeter',
1275
+ routerLink: ['/extensions/greet'],
1276
+ // Icon can be any of https://core.clarity.design/foundation/icons/shapes/
1277
+ icon: 'cursor-hand-open',
1278
+ }],
1279
+ },
1280
+ // Add this section before the "settings" section
1281
+ 'settings'),
1282
+ ];
1283
+ ```
1284
+
1285
+ ### New (React Dashboard)
1286
+
1287
+ ```tsx
1288
+ import { defineDashboardExtension } from '@vendure/dashboard';
1289
+
1290
+ defineDashboardExtension({
1291
+ routes: [
1292
+ {
1293
+ path: '/my-custom-page',
1294
+ component: () => <div>My Custom Page</div>,
1295
+ navMenuItem: {
1296
+ // The section where this item should appear
1297
+ sectionId: 'catalog',
1298
+ // Unique identifier for this menu item
1299
+ id: 'my-custom-page',
1300
+ // Display text in the navigation
1301
+ title: 'My Custom Page',
1302
+ // Optional: URL if different from path
1303
+ url: '/my-custom-page',
1304
+ },
1305
+ },
1306
+ ],
1307
+ });
1308
+ ```
1309
+
1310
+ ## Action Bar Items
1311
+
1312
+ ### Old (Angular)
1313
+ ```ts
1314
+ import { addActionBarItem } from '@vendure/admin-ui/core';
1315
+
1316
+ export default [
1317
+ addActionBarItem({
1318
+ id: 'print-invoice',
1319
+ locationId: 'order-detail',
1320
+ label: 'Print invoice',
1321
+ icon: 'printer',
1322
+ routerLink: route => {
1323
+ const id = route.snapshot.params.id;
1324
+ return ['./extensions/order-invoices', id];
1325
+ },
1326
+ requiresPermission: 'ReadOrder',
1327
+ }),
1328
+ ];
1329
+ ```
1330
+
1331
+ ### New (React Dashboard)
1332
+
1333
+ ```tsx
1334
+ import { Button, defineDashboardExtension } from '@vendure/dashboard';
1335
+ import { useState } from 'react';
1336
+
1337
+ defineDashboardExtension({
1338
+ actionBarItems: [
1339
+ {
1340
+ pageId: 'product-detail',
1341
+ component: ({ context }) => {
1342
+ const [count, setCount] = useState(0);
1343
+ return (
1344
+ <Button type="button" variant="secondary" onClick={() => setCount(x => x + 1)}>
1345
+ Counter: {count}
1346
+ </Button>
1347
+ );
1348
+ },
1349
+ },
1350
+ ],
1351
+ });
1352
+ ```
1353
+
1354
+ ## Custom Detail Components
1355
+
1356
+ ### Old (Angular)
1357
+ ```ts title="src/plugins/cms/ui/components/product-info/product-info.component.ts"
1358
+ import { Component, OnInit } from '@angular/core';
1359
+ import { Observable, switchMap } from 'rxjs';
1360
+ import { FormGroup } from '@angular/forms';
1361
+ import { DataService, CustomDetailComponent, SharedModule } from '@vendure/admin-ui/core';
1362
+ import { CmsDataService } from '../../providers/cms-data.service';
1363
+
1364
+ @Component({
1365
+ template: `
1366
+ <vdr-card title="CMS Info">
1367
+ <pre>{{ extraInfo$ | async | json }}</pre>
1368
+ </vdr-card>`,
1369
+ standalone: true,
1370
+ providers: [CmsDataService],
1371
+ imports: [SharedModule],
1372
+ })
1373
+ export class ProductInfoComponent implements CustomDetailComponent, OnInit {
1374
+ // These two properties are provided by Vendure and will vary
1375
+ // depending on the particular detail page you are embedding this
1376
+ // component into. In this case, it will be a "product" entity.
1377
+ entity$: Observable<any>
1378
+ detailForm: FormGroup;
1379
+
1380
+ extraInfo$: Observable<any>;
1381
+
1382
+ constructor(private cmsDataService: CmsDataService) {
1383
+ }
1384
+
1385
+ ngOnInit() {
1386
+ this.extraInfo$ = this.entity$.pipe(
1387
+ switchMap(entity => this.cmsDataService.getDataFor(entity.id))
1388
+ );
1389
+ }
1390
+ }
1391
+ ```
1392
+
1393
+ ### New (React Dashboard)
1394
+
1395
+ ```tsx title="src/plugins/my-plugin/dashboard/index.tsx"
1396
+ import { defineDashboardExtension } from '@vendure/dashboard';
1397
+
1398
+ defineDashboardExtension({
1399
+ pageBlocks: [
1400
+ {
1401
+ id: 'related-articles',
1402
+ title: 'Related Articles',
1403
+ location: {
1404
+ // This is the pageId of the page where this block will be
1405
+ pageId: 'product-detail',
1406
+ // can be "main" or "side"
1407
+ column: 'side',
1408
+ position: {
1409
+ // Blocks are positioned relative to existing blocks on
1410
+ // the page.
1411
+ blockId: 'facet-values',
1412
+ // Can be "before", "after" or "replace"
1413
+ // Here we'll place it after the `facet-values` block.
1414
+ order: 'after',
1415
+ },
1416
+ },
1417
+ component: ({ context }) => {
1418
+ // In the component, you can use the `context` prop to
1419
+ // access the entity and the form instance.
1420
+ return <div className="text-sm">Articles related to {context.entity.name}</div>;
1421
+ },
1422
+ },
1423
+ ],
1424
+ });
1425
+ ```
1426
+
1427
+ ## Page Tabs
1428
+
1429
+ ### Old (Angular)
1430
+ ```ts
1431
+ import { registerPageTab } from '@vendure/admin-ui/core';
1432
+
1433
+ import { ReviewListComponent } from './components/review-list/review-list.component';
1434
+
1435
+ export default [
1436
+ registerPageTab({
1437
+ location: 'product-detail',
1438
+ tab: 'Reviews',
1439
+ route: 'reviews',
1440
+ tabIcon: 'star',
1441
+ component: ReviewListComponent,
1442
+ }),
1443
+ ];
1444
+ ```
1445
+
1446
+ ### New (React Dashboard)
1447
+
1448
+ Page tabs are not supported by the Dashboard. Suggest alternative such as a new route.
1449
+
1450
+ ## Widgets
1451
+
1452
+ ### Old (Angular)
1453
+ ```ts title="src/plugins/reviews/ui/components/reviews-widget/reviews-widget.component.ts"
1454
+ import { Component, OnInit } from '@angular/core';
1455
+ import { DataService, SharedModule } from '@vendure/admin-ui/core';
1456
+ import { Observable } from 'rxjs';
1457
+
1458
+ @Component({
1459
+ selector: 'reviews-widget',
1460
+ template: `
1461
+ <ul>
1462
+ <li *ngFor="let review of pendingReviews$ | async">
1463
+ <a [routerLink]="['/extensions', 'product-reviews', review.id]">{{ review.summary }}</a>
1464
+ <span class="rating">{{ review.rating }} / 5</span>
1465
+ </li>
1466
+ </ul>
1467
+ `,
1468
+ standalone: true,
1469
+ imports: [SharedModule],
1470
+ })
1471
+ export class ReviewsWidgetComponent implements OnInit {
1472
+ pendingReviews$: Observable<any[]>;
1473
+
1474
+ constructor(private dataService: DataService) {}
1475
+
1476
+ ngOnInit() {
1477
+ this.pendingReviews$ = this.dataService.query(gql`
1478
+ query GetAllReviews($options: ProductReviewListOptions) {
1479
+ productReviews(options: $options) {
1480
+ items {
1481
+ id
1482
+ createdAt
1483
+ authorName
1484
+ summary
1485
+ rating
1486
+ }
1487
+ }
1488
+ }`, {
1489
+ options: {
1490
+ filter: { state: { eq: 'new' } },
1491
+ take: 10,
1492
+ },
1493
+ })
1494
+ .mapStream(data => data.productReviews.items);
1495
+ }
1496
+ }
1497
+ ```
1498
+
1499
+ ```ts title="src/plugins/reviews/ui/providers.ts"
1500
+ import { registerDashboardWidget } from '@vendure/admin-ui/core';
1501
+
1502
+ export default [
1503
+ registerDashboardWidget('reviews', {
1504
+ title: 'Latest reviews',
1505
+ supportedWidths: [4, 6, 8, 12],
1506
+ requiresPermissions: ['ReadReview'],
1507
+ loadComponent: () =>
1508
+ import('./reviews-widget/reviews-widget.component').then(
1509
+ m => m.ReviewsWidgetComponent,
1510
+ ),
1511
+ }),
1512
+ ];
1513
+ ```
1514
+
1515
+ ### New (React Dashboard)
1516
+
1517
+ ```tsx title="custom-widget.tsx"
1518
+ import { Badge, DashboardBaseWidget, useLocalFormat, useWidgetFilters } from '@vendure/dashboard';
1519
+
1520
+ export function CustomWidget() {
1521
+ const { dateRange } = useWidgetFilters();
1522
+ const { formatDate } = useLocalFormat();
1523
+ return (
1524
+ <DashboardBaseWidget id="custom-widget" title="Custom Widget" description="This is a custom widget">
1525
+ <div className="flex flex-wrap gap-1">
1526
+ <span>Displaying results from</span>
1527
+ <Badge variant="secondary">{formatDate(dateRange.from)}</Badge>
1528
+ <span>to</span>
1529
+ <Badge variant="secondary">{formatDate(dateRange.to)}</Badge>
1530
+ </div>
1531
+ </DashboardBaseWidget>
1532
+ );
1533
+ }
1534
+ ```
1535
+
1536
+ ```tsx title="index.tsx"
1537
+ import { defineDashboardExtension } from '@vendure/dashboard';
1538
+
1539
+ import { CustomWidget } from './custom-widget';
1540
+
1541
+ defineDashboardExtension({
1542
+ widgets: [
1543
+ {
1544
+ id: 'custom-widget',
1545
+ name: 'Custom Widget',
1546
+ component: CustomWidget,
1547
+ defaultSize: { w: 3, h: 3 },
1548
+ },
1549
+ ],
1550
+ });
1551
+ ```
1552
+ ````
1553
+
1554
+ </div>
1555
+
1556
+ :::tip
1557
+ The full prompt is quite large, so it can make sense to first clear the current LLM context,
1558
+ e.g. with `/clear` in Claude Code or `/new` in Codex CLI
1559
+ :::
1560
+
1561
+ ### Claude Skills
1562
+
1563
+ If you use Claude Code, you can use [Agent Skills](https://docs.claude.com/en/docs/agents-and-tools/agent-skills/overview) to set
1564
+ up a specialized skill for migrating plugins. This has the advantage that you do not need to continually paste in the full prompt,
1565
+ and it can also be potentially more token-efficient.
1566
+
1567
+ To set up a the skill, run this from the root of your project:
1568
+
1569
+ ```
1570
+ npx degit vendure-ecommerce/vendure/.claude/skills#minor .claude/skills
1571
+ ```
1572
+
1573
+ This command uses [degit](https://github.com/Rich-Harris/degit) to copy over the vendure-dashboard-migration skill to
1574
+ your local `./claude/skills` directory.
1575
+
1576
+ You can then have Claude Code use the skill with a prompt like:
1577
+
1578
+ ```
1579
+ Use the vendure-dashboard-migration skill to migrate
1580
+ @src/plugins/my-plugin to use the dashboard
1581
+ ```
1582
+
1583
+ :::note
1584
+ The individual files in the skill contain the exact same content as the full prompt above,
1585
+ but are more easily reused and can be more token-efficient
1586
+ :::
1587
+
1588
+ ### Manual Cleanup
1589
+
1590
+ It is very likely you'll still need to do _some_ manual cleanup after an AI-assisted migration. You might run into
1591
+ things like:
1592
+
1593
+ - Non-optimum styling choices
1594
+ - Issues with the [tsconfig setup](/guides/extending-the-dashboard/getting-started/#installation--setup) not being perfectly implemented.
1595
+ - For more complex repo structures like a monorepo with plugins as separate libs, you may need to manually implement
1596
+ the initial setup of the config files.
1597
+
1598
+ ## Manual Migration
1599
+
1600
+ If you would rather do a full manual migration, you should first follow the [Dashboard Getting Started guide](/guides/extending-the-dashboard/getting-started/)
1601
+ and the [Extending the Dashboard guide](http://localhost:3001/guides/extending-the-dashboard/extending-overview/).
1602
+
1603
+ The remainder of this document details specific features, and how they are now implemented in the new Dashboard.
1604
+
1605
+ ### Forms
1606
+
1607
+ Forms in the Angular Admin UI used `vdr-form-field` components within a `form-grid` class. In the Dashboard, forms use `FormFieldWrapper` with react-hook-form, wrapped in either `DetailFormGrid` for grid layouts or div containers with `space-y-6` for vertical spacing.
1608
+
1609
+ | Admin UI | Dashboard | Imported From | Notes |
1610
+ |----------|-----------|---------------|-------|
1611
+ | `vdr-form-field` | `FormFieldWrapper` | `@vendure/dashboard` | Uses react-hook-form |
1612
+ | `form-grid` (class) | `DetailFormGrid` | `@vendure/dashboard` | For grid layouts |
1613
+ | `vdr-rich-text-editor` | `RichTextInput` | `@vendure/dashboard` | |
1614
+ | - | `Input` | `@vendure/dashboard` | Basic text input |
1615
+ | `FormGroup` | `useForm` | `react-hook-form` | Form state management |
1616
+
1617
+ ```tsx
1618
+ <PageBlock column="main" blockId="main-form">
1619
+ <DetailFormGrid>
1620
+ <FormFieldWrapper
1621
+ control={form.control}
1622
+ name="title"
1623
+ label="Title"
1624
+ render={({ field }) => <Input {...field} />}
1625
+ />
1626
+ </DetailFormGrid>
1627
+ <div className="space-y-6">
1628
+ <FormFieldWrapper
1629
+ control={form.control}
1630
+ name="body"
1631
+ label="Content"
1632
+ render={({ field }) => (
1633
+ <RichTextInput value={field.value ?? ''} onChange={field.onChange} />
1634
+ )}
1635
+ />
1636
+ </div>
1637
+ </PageBlock>
1638
+ ```
1639
+
1640
+ ### Custom Field Inputs
1641
+
1642
+ Custom field inputs now use the `DashboardFormComponent` type and are registered via `customFormComponents.customFields` in the Dashboard extension definition. Components receive `value`, `onChange`, and `name` props, and can use `useFormContext()` to access field state and errors.
1643
+
1644
+ | Admin UI | Dashboard | Imported From | Notes |
1645
+ |----------|-----------|---------------|-------|
1646
+ | `FormInputComponent<T>` | `DashboardFormComponent` | `@vendure/dashboard` | Type for custom field components |
1647
+ | `registerFormInputComponent()` | `customFormComponents.customFields` | `@vendure/dashboard` | Registration method |
1648
+ | `formControl` (prop) | `value`, `onChange`, `name` (props) | - | Component receives these props |
1649
+ | - | `useFormContext()` | `react-hook-form` | Access field state and errors |
1650
+
1651
+ ```tsx
1652
+ export const ColorPickerComponent: DashboardFormComponent = ({ value, onChange, name }) => {
1653
+ const { getFieldState } = useFormContext();
1654
+ const error = getFieldState(name).error;
1655
+
1656
+ return (
1657
+ <Input value={value || ''} onChange={e => onChange(e.target.value)} />
1658
+ );
1659
+ };
1660
+
1661
+ // Register in index.tsx
1662
+ defineDashboardExtension({
1663
+ customFormComponents: {
1664
+ customFields: [
1665
+ { id: 'color-picker', component: ColorPickerComponent },
1666
+ ],
1667
+ },
1668
+ });
1669
+ ```
1670
+
1671
+ ### List Pages
1672
+
1673
+ List pages migrate from `TypedBaseListComponent` to the `ListPage` component. The `ListPage` automatically generates columns from the GraphQL query fields. Use `customizeColumns` to customize specific columns (e.g., linking with `DetailPageButton`), `defaultVisibility` to control which columns show by default, and `defaultColumnOrder` to set column order.
1674
+
1675
+ | Admin UI | Dashboard | Imported From | Notes |
1676
+ |----------|-----------|---------------|-------|
1677
+ | `TypedBaseListComponent` | `ListPage` | `@vendure/dashboard` | Main list component |
1678
+ | `vdr-data-table-2` | `ListPage` | `@vendure/dashboard` | Auto-generates columns |
1679
+ | `vdr-dt2-column` | `customizeColumns` | - | Prop on `ListPage` |
1680
+ | `[hiddenByDefault]` | `defaultVisibility` | - | Prop on `ListPage` |
1681
+ | `registerRouteComponent()` | `DashboardRouteDefinition` | `@vendure/dashboard` | Route registration |
1682
+ | `[routerLink]` | `DetailPageButton` | `@vendure/dashboard` | For linking to detail pages |
1683
+
1684
+ ```tsx
1685
+ export const articleList: DashboardRouteDefinition = {
1686
+ path: '/articles',
1687
+ component: route => (
1688
+ <ListPage
1689
+ pageId="article-list"
1690
+ title="Articles"
1691
+ listQuery={getArticleList}
1692
+ deleteMutation={deleteArticleDocument}
1693
+ route={route}
1694
+ customizeColumns={{
1695
+ title: {
1696
+ cell: ({ row }) => <DetailPageButton id={row.original.id} label={row.original.title} />,
1697
+ },
1698
+ }}
1699
+ defaultVisibility={{
1700
+ title: true,
1701
+ authorName: true,
1702
+ }}
1703
+ >
1704
+ <PageActionBarRight>
1705
+ <Button asChild>
1706
+ <Link to="./new"><PlusIcon /> New article</Link>
1707
+ </Button>
1708
+ </PageActionBarRight>
1709
+ </ListPage>
1710
+ ),
1711
+ };
1712
+ ```
1713
+
1714
+ **Important**: When using `defaultVisibility`, only specify visible columns with `true`. The `id`, `createdAt`, and `updatedAt` columns are handled automatically. If a custom `cell` function accesses fields other than the one being rendered, declare them in `meta.dependencies`.
1715
+
1716
+ ### Detail Pages
1717
+
1718
+ Detail pages migrate from `TypedBaseDetailComponent` to the `useDetailPage` hook. The hook handles form initialization, entity loading, and mutations. Use `detailPageRouteLoader` for the route loader, and structure the page with `Page`, `PageActionBar`, `PageLayout`, `PageBlock`, and `DetailFormGrid` components.
1719
+
1720
+ | Admin UI | Dashboard | Imported From | Notes |
1721
+ |----------|-----------|---------------|-------|
1722
+ | `TypedBaseDetailComponent` | `useDetailPage()` | `@vendure/dashboard` | Hook for detail page logic |
1723
+ | `this.init()` | `useDetailPage()` | `@vendure/dashboard` | Automatic initialization |
1724
+ | `this.entity$` | `entity` | - | Returned from `useDetailPage` |
1725
+ | `FormBuilder` | `form` | - | Returned from `useDetailPage` |
1726
+ | `dataService.mutate()` | `submitHandler` | - | Returned from `useDetailPage` |
1727
+ | `vdr-page-detail-layout` | `PageLayout` | `@vendure/dashboard` | Layout component |
1728
+ | `vdr-page-block` | `PageBlock` | `@vendure/dashboard` | Content block |
1729
+ | `registerRouteComponent()` | `detailPageRouteLoader()` | `@vendure/dashboard` | Route loader helper |
1730
+
1731
+ ```tsx
1732
+ export const articleDetail: DashboardRouteDefinition = {
1733
+ path: '/articles/$id',
1734
+ loader: detailPageRouteLoader({
1735
+ queryDocument: articleDetailDocument,
1736
+ breadcrumb: (isNew, entity) => [
1737
+ { path: '/articles', label: 'Articles' },
1738
+ isNew ? 'New article' : entity?.title,
1739
+ ],
1740
+ }),
1741
+ component: route => {
1742
+ const { form, submitHandler, entity, isPending, refreshEntity } = useDetailPage({
1743
+ queryDocument: articleDetailDocument,
1744
+ createDocument: createArticleDocument,
1745
+ updateDocument: updateArticleDocument,
1746
+ setValuesForUpdate: article => ({
1747
+ title: article?.title ?? '',
1748
+ slug: article?.slug ?? '',
1749
+ }),
1750
+ params: { id: route.useParams().id },
1751
+ onSuccess: async data => {
1752
+ toast.success('Successfully updated');
1753
+ },
1754
+ });
1755
+
1756
+ return (
1757
+ <Page pageId="article-detail" form={form} submitHandler={submitHandler}>
1758
+ <PageLayout>
1759
+ <PageBlock column="main" blockId="main-form">
1760
+ <DetailFormGrid>
1761
+ <FormFieldWrapper control={form.control} name="title" label="Title"
1762
+ render={({ field }) => <Input {...field} />} />
1763
+ </DetailFormGrid>
1764
+ </PageBlock>
1765
+ </PageLayout>
1766
+ </Page>
1767
+ );
1768
+ },
1769
+ };
1770
+ ```
1771
+
1772
+ **Important**: `PageBlock` already renders as a card, so never nest Card components inside it. Use `refreshEntity` to manually reload entity data after mutations. Ensure vertical spacing of 6 units for components not in `DetailFormGrid`.
1773
+
1774
+ ### Nav Menu Items
1775
+
1776
+ Nav menu items are now configured via the `navMenuItem` property on route definitions within the `routes` array. Specify `sectionId` (e.g., 'catalog'), unique `id`, and `title`.
1777
+
1778
+ | Admin UI | Dashboard | Imported From | Notes |
1779
+ |----------|-----------|---------------|-------|
1780
+ | `addNavMenuSection()` | `navMenuItem` | - | Defined on route in `routes` array |
1781
+ | `label` | `title` | - | Display text |
1782
+ | `routerLink` | `path` | - | Route path |
1783
+ | `icon` | - | - | Not supported in Dashboard |
1784
+
1785
+ ```tsx
1786
+ defineDashboardExtension({
1787
+ routes: [
1788
+ {
1789
+ path: '/my-custom-page',
1790
+ component: () => <div>My Custom Page</div>,
1791
+ navMenuItem: {
1792
+ sectionId: 'catalog',
1793
+ id: 'my-custom-page',
1794
+ title: 'My Custom Page',
1795
+ },
1796
+ },
1797
+ ],
1798
+ });
1799
+ ```
1800
+
1801
+ ### Action Bar Items
1802
+
1803
+ Action bar items migrate from `addActionBarItem` to the `actionBarItems` array in the Dashboard extension. Each item specifies a `pageId` and a `component` function that receives `context`.
1804
+
1805
+ | Admin UI | Dashboard | Imported From | Notes |
1806
+ |----------|-----------|---------------|-------|
1807
+ | `addActionBarItem()` | `actionBarItems` | - | Array in `defineDashboardExtension` |
1808
+ | `locationId` | `pageId` | - | Identifies target page |
1809
+ | `label` | - | - | Render button/component directly |
1810
+ | `icon` | - | `lucide-react` | Use icon components in button |
1811
+ | `routerLink` | `Link` / `useNavigate()` | `@tanstack/react-router` | For navigation |
1812
+
1813
+ ```tsx
1814
+ defineDashboardExtension({
1815
+ actionBarItems: [
1816
+ {
1817
+ pageId: 'product-detail',
1818
+ component: ({ context }) => (
1819
+ <Button type="button" variant="secondary" onClick={() => handleAction()}>
1820
+ Custom Action
1821
+ </Button>
1822
+ ),
1823
+ },
1824
+ ],
1825
+ });
1826
+ ```
1827
+
1828
+ ### Custom Detail Components (Page Blocks)
1829
+
1830
+ Custom detail components (Angular `CustomDetailComponent`) are now implemented as page blocks via the `pageBlocks` array. Each block specifies `id`, `title`, `location` (pageId, column, position), and a `component` function that receives `context` with `entity` and form access.
1831
+
1832
+ | Admin UI | Dashboard | Imported From | Notes |
1833
+ |----------|-----------|---------------|-------|
1834
+ | `CustomDetailComponent` | `pageBlocks` | - | Array in `defineDashboardExtension` |
1835
+ | `entity$` (Observable) | `context.entity` | - | Available in component function |
1836
+ | `detailForm` | `context.form` | - | Available in component function |
1837
+ | `registerCustomDetailComponent()` | `pageBlocks[].location` | - | Positioning configuration |
1838
+
1839
+ ```tsx
1840
+ defineDashboardExtension({
1841
+ pageBlocks: [
1842
+ {
1843
+ id: 'related-articles',
1844
+ title: 'Related Articles',
1845
+ location: {
1846
+ pageId: 'product-detail',
1847
+ column: 'side',
1848
+ position: { blockId: 'facet-values', order: 'after' },
1849
+ },
1850
+ component: ({ context }) => (
1851
+ <div>Articles related to {context.entity.name}</div>
1852
+ ),
1853
+ },
1854
+ ],
1855
+ });
1856
+ ```
1857
+
1858
+ ### Page Tabs
1859
+
1860
+ Page tabs (`registerPageTab`) are not supported in the Dashboard. Consider alternative approaches such as creating a new route or using page blocks.
1861
+
1862
+ | Admin UI | Dashboard | Imported From | Notes |
1863
+ |----------|-----------|---------------|-------|
1864
+ | `registerPageTab()` | - | - | Not supported; use routes or page blocks instead |
1865
+
1866
+ ### Widgets
1867
+
1868
+ Dashboard widgets migrate from `registerDashboardWidget` to the `widgets` array. Each widget specifies `id`, `name`, `component`, and `defaultSize`. Widget components can use `useWidgetFilters()` and `useLocalFormat()` hooks, and should wrap content in `DashboardBaseWidget`.
1869
+
1870
+ | Admin UI | Dashboard | Imported From | Notes |
1871
+ |----------|-----------|---------------|-------|
1872
+ | `registerDashboardWidget()` | `widgets` | - | Array in `defineDashboardExtension` |
1873
+ | `title` | `name` | - | Widget display name |
1874
+ | `loadComponent` | `component` | - | Widget component function |
1875
+ | `supportedWidths` | `defaultSize` | - | Object with `w` and `h` properties |
1876
+ | - | `DashboardBaseWidget` | `@vendure/dashboard` | Wrapper component for widgets |
1877
+ | - | `useWidgetFilters()` | `@vendure/dashboard` | Access date range filters |
1878
+ | - | `useLocalFormat()` | `@vendure/dashboard` | Formatting utilities |
1879
+
1880
+ ```tsx
1881
+ export function CustomWidget() {
1882
+ const { dateRange } = useWidgetFilters();
1883
+ const { formatDate } = useLocalFormat();
1884
+ return (
1885
+ <DashboardBaseWidget id="custom-widget" title="Custom Widget" description="Widget description">
1886
+ <div>
1887
+ <Badge variant="secondary">{formatDate(dateRange.from)}</Badge>
1888
+ to
1889
+ <Badge variant="secondary">{formatDate(dateRange.to)}</Badge>
1890
+ </div>
1891
+ </DashboardBaseWidget>
1892
+ );
1893
+ }
1894
+
1895
+ defineDashboardExtension({
1896
+ widgets: [
1897
+ { id: 'custom-widget', name: 'Custom Widget', component: CustomWidget, defaultSize: { w: 3, h: 3 } },
1898
+ ],
1899
+ });
1900
+ ```
1901
+
1902
+