@spree/docs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +54 -0
  2. package/dist/api-reference/platform/authentication.md +38 -0
  3. package/dist/api-reference/store-api/authentication.md +188 -0
  4. package/dist/api-reference/store-api/errors.md +277 -0
  5. package/dist/api-reference/store-api/idempotency.md +129 -0
  6. package/dist/api-reference/store-api/introduction.md +34 -0
  7. package/dist/api-reference/store-api/localization.md +279 -0
  8. package/dist/api-reference/store-api/metadata.md +160 -0
  9. package/dist/api-reference/store-api/monetary-amounts.md +65 -0
  10. package/dist/api-reference/store-api/querying.md +399 -0
  11. package/dist/api-reference/store-api/rate-limitting.md +103 -0
  12. package/dist/api-reference/store-api/relations.md +185 -0
  13. package/dist/api-reference/storefront/authentication.md +88 -0
  14. package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
  15. package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
  16. package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
  17. package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
  18. package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
  19. package/dist/api-reference/v2/introduction.md +22 -0
  20. package/dist/api-reference/v2/pagination.md +37 -0
  21. package/dist/api-reference/webhooks-events.md +883 -0
  22. package/dist/developer/admin/admin.md +205 -0
  23. package/dist/developer/admin/authentication.md +59 -0
  24. package/dist/developer/admin/components.md +711 -0
  25. package/dist/developer/admin/custom-css.md +243 -0
  26. package/dist/developer/admin/custom-javascript.md +116 -0
  27. package/dist/developer/admin/extending-ui.md +1964 -0
  28. package/dist/developer/admin/form-builder.md +444 -0
  29. package/dist/developer/admin/helper-methods.md +531 -0
  30. package/dist/developer/admin/navigation.md +805 -0
  31. package/dist/developer/admin/tables.md +491 -0
  32. package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
  33. package/dist/developer/cli/quickstart.md +137 -0
  34. package/dist/developer/contributing/creating-an-extension.md +258 -0
  35. package/dist/developer/contributing/developing-spree.md +339 -0
  36. package/dist/developer/contributing/quickstart.md +32 -0
  37. package/dist/developer/contributing/updating-extensions.md +67 -0
  38. package/dist/developer/core-concepts/addresses.md +265 -0
  39. package/dist/developer/core-concepts/adjustments.md +107 -0
  40. package/dist/developer/core-concepts/architecture.md +177 -0
  41. package/dist/developer/core-concepts/calculators.md +323 -0
  42. package/dist/developer/core-concepts/customers.md +230 -0
  43. package/dist/developer/core-concepts/events.md +624 -0
  44. package/dist/developer/core-concepts/imports-exports.md +698 -0
  45. package/dist/developer/core-concepts/inventory.md +191 -0
  46. package/dist/developer/core-concepts/markets.md +250 -0
  47. package/dist/developer/core-concepts/media.md +167 -0
  48. package/dist/developer/core-concepts/metafields.md +187 -0
  49. package/dist/developer/core-concepts/orders.md +328 -0
  50. package/dist/developer/core-concepts/payments.md +710 -0
  51. package/dist/developer/core-concepts/pricing.md +163 -0
  52. package/dist/developer/core-concepts/products.md +360 -0
  53. package/dist/developer/core-concepts/promotions.md +322 -0
  54. package/dist/developer/core-concepts/reports.md +206 -0
  55. package/dist/developer/core-concepts/search-filtering.md +237 -0
  56. package/dist/developer/core-concepts/shipments.md +212 -0
  57. package/dist/developer/core-concepts/slugs.md +111 -0
  58. package/dist/developer/core-concepts/staff-roles.md +123 -0
  59. package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
  60. package/dist/developer/core-concepts/stores.md +117 -0
  61. package/dist/developer/core-concepts/taxes.md +135 -0
  62. package/dist/developer/core-concepts/translations.md +120 -0
  63. package/dist/developer/core-concepts/users.md +299 -0
  64. package/dist/developer/core-concepts/webhooks.md +378 -0
  65. package/dist/developer/create-spree-app/quickstart.md +158 -0
  66. package/dist/developer/customization/api.md +93 -0
  67. package/dist/developer/customization/authentication.md +88 -0
  68. package/dist/developer/customization/checkout.md +204 -0
  69. package/dist/developer/customization/configuration.md +55 -0
  70. package/dist/developer/customization/decorators.md +523 -0
  71. package/dist/developer/customization/dependencies.md +232 -0
  72. package/dist/developer/customization/emails.md +21 -0
  73. package/dist/developer/customization/extensions.md +92 -0
  74. package/dist/developer/customization/metadata.md +236 -0
  75. package/dist/developer/customization/model-preferences.md +130 -0
  76. package/dist/developer/customization/permissions.md +265 -0
  77. package/dist/developer/customization/quickstart.md +229 -0
  78. package/dist/developer/customization/routes.md +24 -0
  79. package/dist/developer/customization/v4/admin-panel.md +78 -0
  80. package/dist/developer/customization/v4/authentication.md +210 -0
  81. package/dist/developer/customization/v4/checkout.md +212 -0
  82. package/dist/developer/customization/v4/deface.md +251 -0
  83. package/dist/developer/customization/v4/images.md +86 -0
  84. package/dist/developer/customization/v4/storefront.md +450 -0
  85. package/dist/developer/deployment/assets.md +87 -0
  86. package/dist/developer/deployment/aws.md +335 -0
  87. package/dist/developer/deployment/caching.md +27 -0
  88. package/dist/developer/deployment/cdn.md +39 -0
  89. package/dist/developer/deployment/database.md +155 -0
  90. package/dist/developer/deployment/docker.md +128 -0
  91. package/dist/developer/deployment/emails.md +77 -0
  92. package/dist/developer/deployment/environment_variables.md +111 -0
  93. package/dist/developer/deployment/heroku.md +51 -0
  94. package/dist/developer/deployment/render.md +95 -0
  95. package/dist/developer/getting-started/quickstart.md +82 -0
  96. package/dist/developer/how-to/custom-payment-method.md +374 -0
  97. package/dist/developer/how-to/custom-promotion.md +373 -0
  98. package/dist/developer/how-to/custom-report.md +387 -0
  99. package/dist/developer/how-to/custom-search-provider.md +230 -0
  100. package/dist/developer/multi-store/quickstart.md +71 -0
  101. package/dist/developer/multi-store/setup.md +38 -0
  102. package/dist/developer/multi-tenant/configuration.md +41 -0
  103. package/dist/developer/multi-tenant/core-concepts.md +75 -0
  104. package/dist/developer/multi-tenant/installation.md +96 -0
  105. package/dist/developer/multi-tenant/quickstart.md +20 -0
  106. package/dist/developer/multi-vendor/installation.md +45 -0
  107. package/dist/developer/multi-vendor/quickstart.md +17 -0
  108. package/dist/developer/sdk/admin/quickstart.md +22 -0
  109. package/dist/developer/sdk/authentication.md +89 -0
  110. package/dist/developer/sdk/configuration.md +225 -0
  111. package/dist/developer/sdk/quickstart.md +82 -0
  112. package/dist/developer/sdk/store/account.md +67 -0
  113. package/dist/developer/sdk/store/cart-checkout.md +140 -0
  114. package/dist/developer/sdk/store/markets.md +151 -0
  115. package/dist/developer/sdk/store/payments.md +96 -0
  116. package/dist/developer/sdk/store/products.md +149 -0
  117. package/dist/developer/sdk/store/wishlists.md +52 -0
  118. package/dist/developer/security/pci_compliance.md +15 -0
  119. package/dist/developer/security/security_policy.md +68 -0
  120. package/dist/developer/storefront/blocks.md +285 -0
  121. package/dist/developer/storefront/custom-css.md +260 -0
  122. package/dist/developer/storefront/custom-javascript.md +166 -0
  123. package/dist/developer/storefront/helper-methods.md +1288 -0
  124. package/dist/developer/storefront/links.md +298 -0
  125. package/dist/developer/storefront/nextjs/architecture.md +150 -0
  126. package/dist/developer/storefront/nextjs/customization.md +141 -0
  127. package/dist/developer/storefront/nextjs/deployment.md +180 -0
  128. package/dist/developer/storefront/nextjs/quickstart.md +92 -0
  129. package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
  130. package/dist/developer/storefront/pages.md +163 -0
  131. package/dist/developer/storefront/sections.md +569 -0
  132. package/dist/developer/storefront/storefront.md +56 -0
  133. package/dist/developer/storefront/themes.md +161 -0
  134. package/dist/developer/tutorial/admin.md +134 -0
  135. package/dist/developer/tutorial/extending-models.md +380 -0
  136. package/dist/developer/tutorial/file-uploads.md +121 -0
  137. package/dist/developer/tutorial/introduction.md +33 -0
  138. package/dist/developer/tutorial/model.md +41 -0
  139. package/dist/developer/tutorial/page-builder.md +487 -0
  140. package/dist/developer/tutorial/rich-text.md +73 -0
  141. package/dist/developer/tutorial/seo.md +332 -0
  142. package/dist/developer/tutorial/storefront.md +352 -0
  143. package/dist/developer/tutorial/testing.md +558 -0
  144. package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
  145. package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
  146. package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
  147. package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
  148. package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
  149. package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
  150. package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
  151. package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
  152. package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
  153. package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
  154. package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
  155. package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
  156. package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
  157. package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
  158. package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
  159. package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
  160. package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
  161. package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
  162. package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
  163. package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
  164. package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
  165. package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
  166. package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
  167. package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
  168. package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
  169. package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
  170. package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
  171. package/dist/developer/upgrades/quickstart.md +36 -0
  172. package/dist/integrations/analytics/google-analytics.md +64 -0
  173. package/dist/integrations/analytics/google-tag-manager.md +78 -0
  174. package/dist/integrations/integrations.md +39 -0
  175. package/dist/integrations/marketing/klaviyo.md +99 -0
  176. package/dist/integrations/payments/adyen.md +90 -0
  177. package/dist/integrations/payments/paypal.md +41 -0
  178. package/dist/integrations/payments/razorpay.md +45 -0
  179. package/dist/integrations/payments/stripe.md +109 -0
  180. package/dist/integrations/search/meilisearch.md +236 -0
  181. package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
  182. package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
  183. package/package.json +27 -0
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: Inventory
3
+ description: Stock locations, stock items, stock movements, and inventory tracking
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Each [Variant](/developer/core-concepts/products#variants) has a `StockItem` that tracks its inventory at a specific location. A variant can have multiple stock items if it's available at multiple stock locations.
9
+
10
+ When products are sold or returned, individual `InventoryUnit` records track each unit through the fulfillment process.
11
+
12
+ Adding new inventory to an out-of-stock product that has backorders will first fill the backorders, then update the available count with the remainder.
13
+
14
+ ### Inventory Model Diagram
15
+
16
+ ```mermaid
17
+ erDiagram
18
+ StockLocation {
19
+ string name
20
+ string admin_name
21
+ boolean active
22
+ boolean default
23
+ boolean backorderable_default
24
+ boolean propagate_all_variants
25
+ }
26
+
27
+ StockItem {
28
+ integer count_on_hand
29
+ boolean backorderable
30
+ integer stock_location_id
31
+ integer variant_id
32
+ }
33
+
34
+ StockMovement {
35
+ integer quantity
36
+ string originator_type
37
+ integer originator_id
38
+ integer stock_item_id
39
+ }
40
+
41
+ StockTransfer {
42
+ string number
43
+ string reference
44
+ integer source_location_id
45
+ integer destination_location_id
46
+ }
47
+
48
+ InventoryUnit {
49
+ string state
50
+ integer variant_id
51
+ integer order_id
52
+ integer shipment_id
53
+ }
54
+
55
+ StockLocation ||--o{ StockItem : "has many"
56
+ StockLocation ||--o{ StockTransfer : "source"
57
+ StockLocation ||--o{ StockTransfer : "destination"
58
+ Variant ||--o{ StockItem : "has many"
59
+ Variant ||--o{ InventoryUnit : "has many"
60
+ StockItem ||--o{ StockMovement : "has many"
61
+ StockTransfer ||--o{ StockMovement : "has many"
62
+ Order ||--o{ InventoryUnit : "has many"
63
+ Shipment ||--o{ InventoryUnit : "has many"
64
+ ```
65
+
66
+ **Key relationships:**
67
+ - **Stock Location** → Contains Stock Items (inventory per variant) and is the source/destination for Stock Transfers
68
+ - **Stock Item** → Tracks quantity (`count_on_hand`) for a specific Variant at a specific Stock Location
69
+ - **Stock Movement** → Records changes to Stock Item quantities (purchases, returns, transfers)
70
+ - **Stock Transfer** → Moves inventory between Stock Locations, creating Stock Movements at source and destination
71
+ - **Inventory Unit** → Represents individual units in [Orders](/developer/core-concepts/orders) and [Shipments](/developer/core-concepts/shipments)
72
+
73
+ ## Inventory Management
74
+
75
+ ### Stock Locations
76
+
77
+ Stock Locations are the physical locations where your inventory is stored and shipped from.
78
+
79
+ Stock Locations can be created in the Admin Panel under **Settings → Stock Locations**, or via the Admin API.
80
+
81
+ Stock Locations have several attributes that define their properties and behavior within the Spree system. Below is a table outlining these attributes:
82
+
83
+ | Attribute | Description | Example Value |
84
+ |-------------------|-----------------------------------------------------------------------------|---------------------|
85
+ | `name` | The public name of the stock location. This is returned in Store API | Warehouse 1 |
86
+ | `admin_name` | The name used internally for the stock location. This is only returned in Admin API. | WH1 Domestic |
87
+ | `address1` | The primary address line for the stock location. | 5th avenue |
88
+ | `address2` | The secondary address line for the stock location. | Suite 100 |
89
+ | `city` | The city where the stock location is based. | New York |
90
+ | `state_id` | The ID of the state where the stock location is based. This references the `State` model. | 1 |
91
+ | `country_id` | The ID of the country where the stock location is based. This references the `Country` model. | 1 |
92
+ | `zipcode` | The postal code for the stock location. | 10001 |
93
+ | `phone` | The contact phone number for the stock location. | 555-1234 |
94
+ | `active` | A boolean indicating whether the stock location is active. Inactive stock locations will not be used in stock calculations or be available for selection during checkout. | `true` |
95
+ | `default` | A boolean indicating whether the stock location is the default one used for new inventory operations. | `false` |
96
+ | `backorderable_default` | A boolean indicating whether new stock items in this location are backorderable by default. | `false` |
97
+ | `propagate_all_variants` | A boolean indicating whether new stock items should be automatically created for all Store variants when a new stock location is added. | `false` |
98
+
99
+ Stock Locations can be easily used for tracking warehouses and other physical locations. They can be used to track separate sections of a warehouse (e.g. aisles, shelves, etc.) or to track different warehouses.
100
+
101
+ You can easily use them with your Point of Sale (POS) system to track inventory at different locations.
102
+
103
+ ### Stock Items
104
+
105
+ Stock Items represent the inventory at a stock location for a specific variant. Stock item count on hand can be increased or decreased by creating stock movements.
106
+
107
+ | Attribute | Description | Example Value |
108
+ |-------------------|-----------------------------------------------------------------------------|---------------------|
109
+ | `stock_location_id` | References the stock location where the stock item belongs. | `1` |
110
+ | `variant_id` | References the variant associated with the stock item. | `32` |
111
+ | `count_on_hand` | The number of items available on hand. | `150` |
112
+ | `backorderable` | Indicates whether the stock item can be backordered. | `true` |
113
+
114
+ ### Stock Transfers
115
+
116
+ Stock transfers allow you to move inventory in bulk from one stock location to another stock location. This is handy when you want to integrate with a POS system or other inventory management system. Or you can just rely on Spree being the source of truth for your inventory.
117
+
118
+ > **INFO:** Stock Transfers can be created in the Admin dashboard or via the Admin API.
119
+
120
+ Here's the list of attributes for the Stock Transfer model:
121
+
122
+ | Attribute | Description | Example Value |
123
+ |--------------------------|-----------------------------------------------------------------------------|---------------------|
124
+ | `number` | The unique number identifier for the stock transfer, generated automatically. | `T123456789` |
125
+ | `reference` | An optional reference field for the stock transfer. | Transfer for Event |
126
+ | `source_location_id` | The ID of the stock location where the stock is transferred from. | `2` |
127
+ | `destination_location_id`| The ID of the stock location where the stock is transferred to. | `3` |
128
+
129
+ Stock transfers are crucial for managing inventory across multiple locations, ensuring that stock levels are accurate and up-to-date.
130
+
131
+ Each Stock Transfer will hold a list of Stock Movements.
132
+
133
+ ### Stock Movements
134
+
135
+ Stock Movements track the movement of the inventory:
136
+
137
+ * when you move inventory between stock locations (via Stock Transfer)
138
+ * when you add inventory to a stock location
139
+ * when you remove inventory from a stock location
140
+ * when customers purchase products
141
+ * when customers return products
142
+
143
+ Here's the list of attributes for the Stock Movement model:
144
+
145
+ | Attribute | Description | Example Value |
146
+ |-------------------|-----------------------------------------------------------------------------|---------------------|
147
+ | `stock_item_id` | References the stock item that the movement belongs to. | `45` |
148
+ | `quantity` | The quantity by which the stock item's count on hand is changed. Positive values indicate stock being added, while negative values indicate stock being removed. | `-10` |
149
+ | `originator_type` | The type of the originator of the stock movement. This is a polymorphic association. | `Spree::Shipment` |
150
+ | `originator_id` | The ID of the originator of the stock movement. This is used in conjunction with `originator_type`. | `2` |
151
+
152
+ Stock Movements are crucial for maintaining accurate inventory levels and for historical tracking of inventory adjustments.
153
+
154
+ ## Inventory Units
155
+
156
+ As we mentioned above, back-ordered, sold, or shipped products are stored as individual `InventoryUnit` objects so they can have relevant information attached to them.
157
+
158
+ We create `InventoryUnit` objects when:
159
+
160
+ * a product is sold (they are added to the Shipment)
161
+ * a product is returned
162
+
163
+ Here's a list of attributes for the Inventory Unit model:
164
+
165
+ | Attribute | Description | Example Value |
166
+ |-------------------|-----------------------------------------------------------------------------|---------------------|
167
+ | `variant_id` | References the variant associated with the inventory unit. | `32` |
168
+ | `order_id` | References the order associated with the inventory unit. | `123` |
169
+ | `shipment_id` | References the shipment associated with the inventory unit. | `77` |
170
+ | `state` | The state of the inventory unit | `on_hand` |
171
+
172
+ Inventory Units states are:
173
+
174
+ * `on_hand` - the inventory unit is on hand
175
+ * `backordered` - the inventory unit is backordered
176
+ * `shipped` - the inventory unit is shipped
177
+
178
+ > **NOTE:** As we noted before, when you add new Stock Items to a Variant (eg. via Admin Panel or Admin API), the first Inventory Units to fulfill are the backordered ones.
179
+
180
+ ## Disabling Inventory Tracking
181
+
182
+ If you don't need to track inventory, you can disable it:
183
+
184
+ - **Per variant** — set `track_inventory` to `false` on a specific variant via the Admin Panel or Admin API
185
+ - **Globally** — disable inventory tracking for the entire store in your Spree configuration
186
+
187
+ ## Related Documentation
188
+
189
+ - [Products](/developer/core-concepts/products) - Product and variant management
190
+ - [Shipments](/developer/core-concepts/shipments) - How inventory relates to shipments
191
+ - [Orders](/developer/core-concepts/orders) - How inventory is allocated to orders
@@ -0,0 +1,250 @@
1
+ ---
2
+ title: Markets
3
+ description: Multi-region commerce with Markets — bundle geography, currency, and locale into distinct selling regions within a single store.
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Markets let you segment a single [Store](/developer/core-concepts/stores) into distinct geographic regions, each with its own currency, locale, and set of countries. For example, an international store might define:
9
+
10
+ - **North America** — USD, English, ships to US and Canada
11
+ - **Europe** — EUR, German, ships to DE, FR, AT, NL
12
+ - **United Kingdom** — GBP, English, ships to GB
13
+
14
+ ```mermaid
15
+ erDiagram
16
+ Store ||--o{ Market : "has many"
17
+ Market ||--o{ MarketCountry : "has many"
18
+ MarketCountry }o--|| Country : "belongs to"
19
+
20
+ Store {
21
+ string name
22
+ string url
23
+ }
24
+
25
+ Market {
26
+ string name
27
+ string currency
28
+ string default_locale
29
+ string supported_locales
30
+ boolean tax_inclusive
31
+ boolean default
32
+ }
33
+
34
+ Country {
35
+ string iso
36
+ string name
37
+ }
38
+ ```
39
+
40
+ ## Market Attributes
41
+
42
+ | Attribute | Description | Example |
43
+ |-----------|-------------|---------|
44
+ | `name` | Human-readable name, unique per store | `North America` |
45
+ | `currency` | ISO 4217 currency code | `USD` |
46
+ | `default_locale` | Default language for this market | `en` |
47
+ | `supported_locales` | All locales available in this market | `["en", "es"]` |
48
+ | `tax_inclusive` | Whether prices include tax (affects display and checkout calculation) | `false` |
49
+ | `default` | Whether this is the fallback market when no country match is found | `true` |
50
+ | `countries` | List of countries in this market | `[{ iso: "US" }, { iso: "CA" }]` |
51
+
52
+ ## How Markets Work
53
+
54
+ When a customer visits your store, their country determines which market applies. The market then sets the currency, locale, and tax behavior for that session.
55
+
56
+ ```
57
+ Customer's Country → Market → Currency + Locale + Tax Zone
58
+ ```
59
+
60
+ The resolution chain:
61
+
62
+ 1. Customer's country is detected (from URL, geolocation, `X-Spree-Country` header, or manual selection)
63
+ 2. Spree finds the market containing that country
64
+ 3. The market's currency and locale become the defaults for the session
65
+ 4. The market's tax zone determines whether prices are shown with or without tax
66
+
67
+ If no market matches the customer's country, the store's **default market** is used.
68
+
69
+ ## Listing Markets
70
+
71
+ Fetch all markets for the current store, including their countries:
72
+
73
+
74
+ ```typescript SDK
75
+ const { data: markets } = await client.markets.list()
76
+ // [
77
+ // {
78
+ // id: "mkt_k5nR8xLq",
79
+ // name: "North America",
80
+ // currency: "USD",
81
+ // default_locale: "en",
82
+ // supported_locales: ["en", "es"],
83
+ // tax_inclusive: false,
84
+ // default: true,
85
+ // countries: [
86
+ // { iso: "US", name: "United States", states_required: true, zipcode_required: true },
87
+ // { iso: "CA", name: "Canada", states_required: true, zipcode_required: true }
88
+ // ]
89
+ // },
90
+ // ...
91
+ // ]
92
+ ```
93
+
94
+ ```bash cURL
95
+ curl 'https://api.mystore.com/api/v3/store/markets' \
96
+ -H 'Authorization: Bearer spree_pk_xxx'
97
+ ```
98
+
99
+
100
+ ## Resolving a Market by Country
101
+
102
+ When you know a customer's country (e.g., from geolocation or a country picker), resolve which market applies:
103
+
104
+
105
+ ```typescript SDK
106
+ const market = await client.markets.resolve('DE')
107
+ // { id: "mkt_gbHJdmfr", name: "Europe", currency: "EUR", tax_inclusive: true, ... }
108
+ ```
109
+
110
+ ```bash cURL
111
+ curl 'https://api.mystore.com/api/v3/store/markets/resolve?country=DE' \
112
+ -H 'Authorization: Bearer spree_pk_xxx'
113
+ ```
114
+
115
+
116
+ Returns the market object on success, or `404` if no market contains that country.
117
+
118
+ This is useful for building a country switcher — resolve the market to show the customer what currency and language they'll get.
119
+
120
+ ## Countries in a Market
121
+
122
+ List countries belonging to a specific market. Useful for populating address form dropdowns during checkout:
123
+
124
+
125
+ ```typescript SDK
126
+ const { data: countries } = await client.markets.countries.list('mkt_k5nR8xLq')
127
+ // [
128
+ // { iso: "CA", name: "Canada", states_required: true, zipcode_required: true },
129
+ // { iso: "US", name: "United States", states_required: true, zipcode_required: true }
130
+ // ]
131
+
132
+ // Get a country with its states (for address form dropdowns)
133
+ const usa = await client.markets.countries.get('mkt_k5nR8xLq', 'US', {
134
+ include: 'states',
135
+ })
136
+ ```
137
+
138
+ ```bash cURL
139
+ # List countries in a market
140
+ curl 'https://api.mystore.com/api/v3/store/markets/mkt_k5nR8xLq/countries' \
141
+ -H 'Authorization: Bearer spree_pk_xxx'
142
+
143
+ # Get a country with its states
144
+ curl 'https://api.mystore.com/api/v3/store/markets/mkt_k5nR8xLq/countries/US?include=states' \
145
+ -H 'Authorization: Bearer spree_pk_xxx'
146
+ ```
147
+
148
+
149
+ You can also fetch countries flat (across all markets) or include the market on a country:
150
+
151
+
152
+ ```typescript SDK
153
+ // All countries across all markets
154
+ const { data: countries } = await client.countries.list()
155
+
156
+ // Get a country with its market details
157
+ const germany = await client.countries.get('DE', { include: 'market' })
158
+ // { iso: "DE", name: "Germany", market: { currency: "EUR", default_locale: "de", tax_inclusive: true } }
159
+ ```
160
+
161
+ ```bash cURL
162
+ # All countries across all markets
163
+ curl 'https://api.mystore.com/api/v3/store/countries' \
164
+ -H 'Authorization: Bearer spree_pk_xxx'
165
+
166
+ # Get a country with its market
167
+ curl 'https://api.mystore.com/api/v3/store/countries/DE?include=market' \
168
+ -H 'Authorization: Bearer spree_pk_xxx'
169
+ ```
170
+
171
+
172
+ ## Currency and Locale
173
+
174
+ Each market defines a currency and set of supported locales. When a market is resolved, its currency and locale become the defaults for the session.
175
+
176
+ You can discover all available currencies and locales (aggregated from all markets) via dedicated endpoints:
177
+
178
+
179
+ ```typescript SDK
180
+ const { data: currencies } = await client.currencies.list()
181
+ // [{ iso_code: "USD", name: "US Dollar", symbol: "$" }, { iso_code: "EUR", name: "Euro", symbol: "€" }]
182
+
183
+ const { data: locales } = await client.locales.list()
184
+ // [{ code: "en", name: "English" }, { code: "de", name: "German" }]
185
+ ```
186
+
187
+ ```bash cURL
188
+ curl 'https://api.mystore.com/api/v3/store/currencies' \
189
+ -H 'Authorization: Bearer spree_pk_xxx'
190
+
191
+ curl 'https://api.mystore.com/api/v3/store/locales' \
192
+ -H 'Authorization: Bearer spree_pk_xxx'
193
+ ```
194
+
195
+
196
+ See [Localization](/api-reference/store-api/localization) for details on how to pass locale, currency, and country headers in API requests.
197
+
198
+ ## Tax Behavior
199
+
200
+ The `tax_inclusive` flag on a market controls how prices are displayed and calculated:
201
+
202
+ - **`tax_inclusive: true`** (common in Europe) — the price shown to the customer already includes tax
203
+ - **`tax_inclusive: false`** (common in the US) — tax is added at checkout on top of the displayed price
204
+
205
+ Each market also resolves a **tax zone** from its default country. This zone determines which tax rates apply when browsing products — before the customer enters a shipping address. Once the customer provides an address at checkout, the actual shipping address takes over for tax calculation.
206
+
207
+ See [Taxes](/developer/core-concepts/taxes) for details on tax zones and rates.
208
+
209
+ ## Pricing Integration
210
+
211
+ Markets integrate with the [Pricing](/developer/core-concepts/pricing) system, enabling market-specific pricing through **Price Lists** with a **Market Rule**. This lets you set different prices for the same product in different markets — beyond just currency conversion.
212
+
213
+ For example, you could price a product at $29.99 in North America and €24.99 in Europe, rather than relying on exchange rate conversion.
214
+
215
+ See [Pricing — Price Rules](/developer/core-concepts/pricing#price-rules) for details on configuring market-specific price lists.
216
+
217
+ ## Setting Up Markets
218
+
219
+ Markets are managed in the admin dashboard under **Settings → Markets**. When you run `rails db:seed`, Spree automatically creates a default market for each store.
220
+
221
+ To create markets programmatically:
222
+
223
+ ```ruby
224
+ # North America market
225
+ current_store.markets.create!(
226
+ name: 'North America',
227
+ currency: 'USD',
228
+ default_locale: 'en',
229
+ countries: [usa, canada],
230
+ default: true
231
+ )
232
+
233
+ # Europe market with tax-inclusive pricing
234
+ current_store.markets.create!(
235
+ name: 'Europe',
236
+ currency: 'EUR',
237
+ default_locale: 'de',
238
+ supported_locales: 'de,en,fr',
239
+ tax_inclusive: true,
240
+ countries: [germany, france, austria, netherlands]
241
+ )
242
+ ```
243
+
244
+ ## Related Documentation
245
+
246
+ - [Stores](/developer/core-concepts/stores) — Multi-store setup and configuration
247
+ - [Pricing](/developer/core-concepts/pricing) — Price Lists, Price Rules, and the Pricing Context
248
+ - [Addresses](/developer/core-concepts/addresses) — Countries, States, and Zones
249
+ - [Localization](/api-reference/store-api/localization) — Locale, currency, and country headers in API requests
250
+ - [Translations](/developer/core-concepts/translations) — Resource and UI translations
@@ -0,0 +1,167 @@
1
+ ---
2
+ title: Media
3
+ sidebarTitle: "Media"
4
+ description: Product media (images, videos), named variants, focal points, and how media is served via the Store API
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ Spree handles uploads, processing, and delivery for product media. Images are automatically converted to WebP format and preprocessed into multiple sizes for optimal performance.
10
+
11
+ ## Product Media
12
+
13
+ Product media uses the `Spree::Asset` model, which provides:
14
+
15
+ - **Multiple media per product** with ordering
16
+ - **Media types** — `image`, `video`, `external_video`
17
+ - **Alt text** for accessibility and SEO
18
+ - **Focal point** coordinates for smart cropping
19
+ - **Preprocessed named variants** for fast delivery
20
+
21
+ Each media item has a `media_type` field that defaults to `image`. The `variant_ids` field indicates which product variants the media is associated with — an empty array means the media belongs to the product as a whole.
22
+
23
+ > **NOTE:** `Spree::Image` is a backward-compatible subclass of `Spree::Asset` that sets `media_type` to `image`. New code should use `Spree::Asset` directly.
24
+
25
+ ### Named Variant Sizes
26
+
27
+ When an image is uploaded, Spree automatically generates optimized versions in the background:
28
+
29
+ | Name | Dimensions | Use Case |
30
+ |------|------------|----------|
31
+ | `mini` | 128x128 | Thumbnails, cart items |
32
+ | `small` | 256x256 | Product listings, galleries |
33
+ | `medium` | 400x400 | Product cards, category pages |
34
+ | `large` | 720x720 | Product detail pages |
35
+ | `xlarge` | 2000x2000 | Zoom, high-resolution displays |
36
+
37
+ All variants are cropped to fill the exact dimensions and converted to WebP format.
38
+
39
+ ## Store API
40
+
41
+ ### Thumbnails (Always Available)
42
+
43
+ Every product response includes a `thumbnail_url` field — ready to use without any expands. Similarly, each variant includes a `thumbnail` URL and a `media_count` counter.
44
+
45
+
46
+ ```typescript SDK
47
+ // List products — thumbnail_url is always included
48
+ const { data: products } = await client.products.list({ limit: 12 })
49
+
50
+ products.forEach(product => {
51
+ product.thumbnail_url // "https://cdn.../tote-front.webp" — no expand needed
52
+ })
53
+ ```
54
+
55
+ ```bash cURL
56
+ # thumbnail_url is always in the response — no ?expand needed
57
+ curl 'https://api.mystore.com/api/v3/store/products?limit=12' \
58
+ -H 'Authorization: Bearer spree_pk_xxx'
59
+ ```
60
+
61
+
62
+ > **WARNING:** Avoid using `?expand=media` on listing pages. This loads **all** media for every product in the response. Use `thumbnail_url` instead and only expand full media on product detail pages.
63
+
64
+ ### Full Media (On Demand)
65
+
66
+ On the product detail page, expand `media` and `variants` to get the full set of media with all named variant URLs:
67
+
68
+
69
+ ```typescript SDK
70
+ const product = await client.products.get('spree-tote', {
71
+ expand: ['media', 'variants'],
72
+ })
73
+
74
+ // Product media gallery
75
+ product.media // [{ id, media_type, product_id, variant_ids, original_url, mini_url, ..., alt, position }, ...]
76
+
77
+ // Each variant has its own thumbnail and media_count
78
+ product.variants?.forEach(variant => {
79
+ variant.thumbnail // "https://cdn.../tote-red.webp" — always available
80
+ variant.media_count // 3 — quick check without loading media
81
+ variant.media // full media array (only with ?expand=media)
82
+ })
83
+ ```
84
+
85
+ ```bash cURL
86
+ curl 'https://api.mystore.com/api/v3/store/products/spree-tote?expand=media,variants' \
87
+ -H 'Authorization: Bearer spree_pk_xxx'
88
+ ```
89
+
90
+
91
+ **Response (media object):**
92
+
93
+ ```json
94
+ {
95
+ "id": "media_k5nR8xLq",
96
+ "media_type": "image",
97
+ "product_id": "prod_86Rf07xd4z",
98
+ "variant_ids": ["variant_m3Rp9wXz"],
99
+ "position": 1,
100
+ "alt": "Front view",
101
+ "focal_point_x": null,
102
+ "focal_point_y": null,
103
+ "external_video_url": null,
104
+ "original_url": "https://cdn.example.com/images/original.jpg",
105
+ "mini_url": "https://cdn.example.com/images/mini.webp",
106
+ "small_url": "https://cdn.example.com/images/small.webp",
107
+ "medium_url": "https://cdn.example.com/images/medium.webp",
108
+ "large_url": "https://cdn.example.com/images/large.webp",
109
+ "xlarge_url": "https://cdn.example.com/images/xlarge.webp"
110
+ }
111
+ ```
112
+
113
+ ### Media Fields Summary
114
+
115
+ | Field | Available on | Always Returned | Description |
116
+ |-------|-------------|:---:|-------------|
117
+ | `thumbnail_url` | Product | Yes | URL to the product's first media |
118
+ | `thumbnail` | Variant | Yes | URL to the variant's first media |
119
+ | `media_count` | Variant | Yes | Number of media items (counter cache) |
120
+ | `media` | Product, Variant | No | Full media array (requires `?expand=media`) |
121
+
122
+ ### Media Object Fields
123
+
124
+ | Field | Type | Description |
125
+ |-------|------|-------------|
126
+ | `id` | string | Prefixed ID (`media_xxx`) |
127
+ | `media_type` | string | `image`, `video`, or `external_video` |
128
+ | `product_id` | string \| null | Owning product prefixed ID |
129
+ | `variant_ids` | string[] | Associated variant prefixed IDs (empty = product-level) |
130
+ | `position` | number | Sort order |
131
+ | `alt` | string \| null | Alt text |
132
+ | `focal_point_x` | number \| null | Horizontal focal point (0.0–1.0) |
133
+ | `focal_point_y` | number \| null | Vertical focal point (0.0–1.0) |
134
+ | `external_video_url` | string \| null | External video URL (YouTube/Vimeo) |
135
+ | `original_url` | string \| null | Full-size image URL |
136
+ | `mini_url` ... `xlarge_url` | string \| null | Named variant URLs |
137
+
138
+ ## Image Processing
139
+
140
+ Spree uses [libvips](https://www.libvips.org/) for image processing. Images are automatically:
141
+
142
+ - Converted to **WebP format** for optimal file size
143
+ - **Preprocessed on upload** into all named variant sizes
144
+ - **Cached** for subsequent requests
145
+
146
+ ## Storage
147
+
148
+ Spree supports two storage service types:
149
+
150
+ | Service | Purpose | Examples |
151
+ |---------|---------|---------|
152
+ | Public storage | Product images, logos, taxon images | S3 public bucket, CDN |
153
+ | Private storage | CSV exports, digital downloads | S3 private bucket |
154
+
155
+ > **INFO:** For production deployments, use cloud storage (S3, GCS, Azure) instead of local disk storage. See [Asset Deployment](/developer/deployment/assets) for configuration details.
156
+
157
+ ## Best Practices
158
+
159
+ - **Use `thumbnail_url`** on listing pages — avoid loading full media via expand
160
+ - **Always provide alt text** for accessibility and SEO
161
+ - **Use named variant sizes** (`mini`, `small`, `medium`, `large`, `xlarge`) for optimal performance
162
+ - **Use a CDN** in production for faster delivery
163
+
164
+ ## Related Documentation
165
+
166
+ - [Products](/developer/core-concepts/products) — Product catalog and media
167
+ - [Deployment — Assets](/developer/deployment/assets) — Storage and CDN configuration