@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,237 @@
1
+ ---
2
+ title: Search & Filtering
3
+ description: "Search, filter, and sort products and other resources via the Store API"
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Spree provides powerful search, filtering, and sorting capabilities for products and other resources. The Store API supports:
9
+
10
+ - Full-text search across product names, descriptions, and SKUs
11
+ - Attribute-based filtering (price range, availability, stock status)
12
+ - Category and taxon filtering
13
+ - Faceted search with filter counts
14
+ - Flexible sorting options
15
+
16
+ ## Product Search
17
+
18
+ Use the `search` parameter for full-text search across product fields:
19
+
20
+
21
+ ```typescript SDK
22
+ const { data: products } = await client.products.list({
23
+ search: 'tote bag',
24
+ limit: 12,
25
+ })
26
+ ```
27
+
28
+ ```bash cURL
29
+ curl 'https://api.mystore.com/api/v3/store/products?q[search]=tote+bag&limit=12' \
30
+ -H 'Authorization: Bearer spree_pk_xxx'
31
+ ```
32
+
33
+
34
+ ## Filtering Products
35
+
36
+ ### By Price Range
37
+
38
+
39
+ ```typescript SDK
40
+ const { data: products } = await client.products.list({
41
+ price_gte: 20,
42
+ price_lte: 100,
43
+ })
44
+ ```
45
+
46
+ ```bash cURL
47
+ curl 'https://api.mystore.com/api/v3/store/products?q[price_gte]=20&q[price_lte]=100' \
48
+ -H 'Authorization: Bearer spree_pk_xxx'
49
+ ```
50
+
51
+
52
+ ### By Availability
53
+
54
+
55
+ ```typescript SDK
56
+ const { data: products } = await client.products.list({
57
+ in_stock: true,
58
+ })
59
+ ```
60
+
61
+ ```bash cURL
62
+ curl 'https://api.mystore.com/api/v3/store/products?q[in_stock]=true' \
63
+ -H 'Authorization: Bearer spree_pk_xxx'
64
+ ```
65
+
66
+
67
+ ### By Category
68
+
69
+
70
+ ```typescript SDK
71
+ // Products in a specific category
72
+ const { data: products } = await client.categories.products.list('clothing/shirts', {
73
+ limit: 12,
74
+ })
75
+
76
+ // Or filter by category ID
77
+ const { data: products } = await client.products.list({
78
+ categories_id_eq: 'ctg_xxx',
79
+ })
80
+ ```
81
+
82
+ ```bash cURL
83
+ # Products in a category
84
+ curl 'https://api.mystore.com/api/v3/store/categories/clothing/shirts/products?limit=12' \
85
+ -H 'Authorization: Bearer spree_pk_xxx'
86
+
87
+ # Filter by category ID
88
+ curl 'https://api.mystore.com/api/v3/store/products?q[categories_id_eq]=ctg_xxx' \
89
+ -H 'Authorization: Bearer spree_pk_xxx'
90
+ ```
91
+
92
+
93
+ ### By Tags
94
+
95
+
96
+ ```typescript SDK
97
+ const { data: products } = await client.products.list({
98
+ tags_cont: 'sale',
99
+ })
100
+ ```
101
+
102
+ ```bash cURL
103
+ curl 'https://api.mystore.com/api/v3/store/products?q[tags_cont]=sale' \
104
+ -H 'Authorization: Bearer spree_pk_xxx'
105
+ ```
106
+
107
+
108
+ ## Sorting
109
+
110
+
111
+ ```typescript SDK
112
+ // Sort by price (low to high)
113
+ const sorted = await client.products.list({
114
+ sort: 'price_low_to_high',
115
+ })
116
+
117
+ // Available sort options:
118
+ // price_low_to_high, price_high_to_low, newest, name_a_z, name_z_a
119
+ ```
120
+
121
+ ```bash cURL
122
+ curl 'https://api.mystore.com/api/v3/store/products?sort=price_low_to_high' \
123
+ -H 'Authorization: Bearer spree_pk_xxx'
124
+ ```
125
+
126
+
127
+ ## Product Filters (Faceted Search)
128
+
129
+ Get available filter options for building a faceted search UI. Returns option values, price ranges, and categories with counts:
130
+
131
+
132
+ ```typescript SDK
133
+ const filters = await client.products.filters()
134
+ // {
135
+ // option_types: [{ name: "size", option_values: [{ name: "Small", count: 12 }, ...] }],
136
+ // price_range: { min: 9.99, max: 199.99 },
137
+ // categories: [{ id: "ctg_xxx", name: "Clothing", count: 45 }],
138
+ // }
139
+
140
+ // Scoped to a specific category
141
+ const categoryFilters = await client.products.filters({
142
+ category_id: 'ctg_xxx',
143
+ })
144
+ ```
145
+
146
+ ```bash cURL
147
+ # All filters
148
+ curl 'https://api.mystore.com/api/v3/store/products/filters' \
149
+ -H 'Authorization: Bearer spree_pk_xxx'
150
+
151
+ # Scoped to a category
152
+ curl 'https://api.mystore.com/api/v3/store/products/filters?category_id=ctg_xxx' \
153
+ -H 'Authorization: Bearer spree_pk_xxx'
154
+ ```
155
+
156
+
157
+ ## Filtering Other Resources
158
+
159
+ The Store API uses query parameters prefixed with `q[]` for filtering any resource collection. Common filter predicates:
160
+
161
+ ### Equality Predicates
162
+
163
+ | Predicate | Description | Example |
164
+ |-----------|-------------|---------|
165
+ | `eq` | Equals | `q[status_eq]=active` |
166
+ | `not_eq` | Not equals | `q[status_not_eq]=archived` |
167
+ | `in` | In array | `q[id_in][]=1&q[id_in][]=2` |
168
+
169
+ ### String Predicates
170
+
171
+ | Predicate | Description | Example |
172
+ |-----------|-------------|---------|
173
+ | `cont` | Contains | `q[name_cont]=shirt` |
174
+ | `start` | Starts with | `q[name_start]=spree` |
175
+ | `end` | Ends with | `q[email_end]=@example.com` |
176
+ | `i_cont` | Case-insensitive contains | `q[name_i_cont]=SHIRT` |
177
+
178
+ ### Comparison Predicates
179
+
180
+ | Predicate | Description | Example |
181
+ |-----------|-------------|---------|
182
+ | `gt` | Greater than | `q[price_gt]=50` |
183
+ | `gteq` | Greater than or equal | `q[quantity_gteq]=10` |
184
+ | `lt` | Less than | `q[price_lt]=100` |
185
+ | `lteq` | Less than or equal | `q[created_at_lteq]=2025-12-31` |
186
+
187
+ ### NULL Predicates
188
+
189
+ | Predicate | Description | Example |
190
+ |-----------|-------------|---------|
191
+ | `null` | Is NULL | `q[deleted_at_null]=true` |
192
+ | `not_null` | Is not NULL | `q[published_at_not_null]=true` |
193
+ | `present` | Is not NULL and not empty | `q[image_present]=true` |
194
+
195
+ > **INFO:** Only attributes explicitly allowed by each resource can be used for filtering. Attempting to filter on unsupported fields will be silently ignored.
196
+
197
+ ## Pagination
198
+
199
+ All list endpoints support pagination:
200
+
201
+
202
+ ```typescript SDK
203
+ const { data: products, meta } = await client.products.list({
204
+ page: 1,
205
+ limit: 24,
206
+ })
207
+ // meta.total_count => 150
208
+ // meta.total_pages => 7
209
+ ```
210
+
211
+ ```bash cURL
212
+ curl 'https://api.mystore.com/api/v3/store/products?page=1&limit=24' \
213
+ -H 'Authorization: Bearer spree_pk_xxx'
214
+ ```
215
+
216
+
217
+ See [Querying](/api-reference/store-api/querying) for the full list of filtering, sorting, and pagination options.
218
+
219
+ ## Search Providers
220
+
221
+ Spree uses a pluggable search provider architecture. The default provider uses SQL (ILIKE + Ransack). For production catalogs with 1,000+ products, we recommend switching to [Meilisearch](/integrations/search/meilisearch) for typo tolerance, relevance ranking, and faster faceted search.
222
+
223
+ ```ruby
224
+ # config/initializers/spree.rb
225
+ Spree.search_provider = 'Spree::SearchProvider::Meilisearch'
226
+ ```
227
+
228
+ No client-side or API changes are needed — the same `q[search]`, filter params, and sort options work with any provider.
229
+
230
+ See [Build a Custom Search Provider](/developer/how-to/custom-search-provider) for architecture details and how to build custom providers.
231
+
232
+ ## Related Documentation
233
+
234
+ - [Products](/developer/core-concepts/products) — Product catalog and listing
235
+ - [Querying](/api-reference/store-api/querying) — API filtering, sorting, and pagination reference
236
+ - [Build a Custom Search Provider](/developer/how-to/custom-search-provider) — Step-by-step guide
237
+ - [Meilisearch Integration](/integrations/search/meilisearch) — Setup guide
@@ -0,0 +1,212 @@
1
+ ---
2
+ title: Shipments
3
+ description: Shipping methods, rates, split shipments, and fulfillment
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ A shipment represents a package being sent to a customer from a [Stock Location](/developer/core-concepts/inventory#stock-locations). Each order can have one or more shipments — Spree automatically splits orders into multiple shipments when items need to ship from different locations or require different shipping methods.
9
+
10
+ ```mermaid
11
+ erDiagram
12
+ Order ||--o{ Shipment : "has many"
13
+ Shipment ||--o{ ShippingRate : "has many"
14
+ Shipment ||--o{ InventoryUnit : "has many"
15
+ Shipment }o--|| StockLocation : "ships from"
16
+ Shipment }o--|| ShippingMethod : "selected method"
17
+ ShippingMethod ||--o{ ShippingRate : "has many"
18
+ ShippingMethod }o--o{ Zone : "serves"
19
+ ShippingMethod }o--o{ ShippingCategory : "handles"
20
+ ShippingMethod }o--o{ Store : "available in"
21
+ Product }o--|| ShippingCategory : "belongs to"
22
+
23
+ Shipment {
24
+ string number
25
+ string tracking
26
+ string state
27
+ decimal cost
28
+ datetime shipped_at
29
+ }
30
+
31
+ ShippingMethod {
32
+ string name
33
+ string tracking_url
34
+ integer position
35
+ }
36
+
37
+ ShippingRate {
38
+ decimal cost
39
+ boolean selected
40
+ }
41
+ ```
42
+
43
+ **Key relationships:**
44
+ - **Shipment** tracks delivery of items from a [Stock Location](/developer/core-concepts/inventory#stock-locations)
45
+ - **Shipping Method** defines the carrier/service (UPS, FedEx, etc.)
46
+ - **Shipping Rate** represents the calculated cost for a method
47
+ - **[Zone](/developer/core-concepts/addresses#zones)** defines geographic regions for shipping availability
48
+ - **Shipping Category** groups products with similar shipping requirements
49
+
50
+ ## Shipment Attributes
51
+
52
+ | Attribute | Description | Example |
53
+ |-----------|-------------|---------|
54
+ | `number` | Unique shipment identifier | `H12345678901` |
55
+ | `tracking` | Carrier tracking number | `1Z999AA10123456784` |
56
+ | `state` | Current shipment state | `shipped` |
57
+ | `cost` | Shipping cost | `9.99` |
58
+ | `shipped_at` | When the shipment was shipped | `2025-07-21T14:36:00Z` |
59
+ | `stock_location` | Where items ship from | `Warehouse NYC` |
60
+ | `selected_shipping_rate` | The rate chosen by the customer | `{ cost: 9.99, name: "UPS Ground" }` |
61
+
62
+ ## Shipment States
63
+
64
+ **Step 1: pending**
65
+
66
+ The shipment has backordered inventory or the order is not yet paid.
67
+
68
+ **Step 2: ready**
69
+
70
+ All items are in stock and the order is paid. Ready to ship.
71
+
72
+ **Step 3: shipped**
73
+
74
+ The shipment is on its way to the customer.
75
+
76
+ **Step 4: canceled**
77
+
78
+ The shipment was canceled. All items are restocked.
79
+
80
+
81
+ ## Selecting Shipping Rates
82
+
83
+ During checkout, after the customer provides a shipping address, Spree calculates available shipping rates for each shipment. The customer must select a rate before proceeding.
84
+
85
+
86
+ ```typescript SDK
87
+ // Get shipments with available shipping rates
88
+ const order = await client.orders.get(orderId, {
89
+ expand: ['shipments'],
90
+ })
91
+
92
+ // Each shipment has available shipping rates
93
+ order.shipments?.forEach(shipment => {
94
+ console.log(shipment.number) // "H12345678901"
95
+ console.log(shipment.shipping_rates) // [{ id: "sr_xxx", name: "UPS Ground", cost: "9.99", selected: true }, ...]
96
+ })
97
+
98
+ // Select a shipping rate
99
+ await client.carts.shipments.update(cartId, shipment.id, {
100
+ selected_shipping_rate_id: 'sr_xxx',
101
+ })
102
+ ```
103
+
104
+ ```bash cURL
105
+ # Get shipments
106
+ curl 'https://api.mystore.com/api/v3/store/carts/cart_xxx?expand=shipments' \
107
+ -H 'Authorization: Bearer spree_pk_xxx' \
108
+ -H 'X-Spree-Token: abc123'
109
+
110
+ # Select a shipping rate
111
+ curl -X PATCH 'https://api.mystore.com/api/v3/store/carts/cart_xxx/shipments/shp_xxx' \
112
+ -H 'Authorization: Bearer spree_pk_xxx' \
113
+ -H 'X-Spree-Token: abc123' \
114
+ -H 'Content-Type: application/json' \
115
+ -d '{ "selected_shipping_rate_id": "sr_xxx" }'
116
+ ```
117
+
118
+
119
+ ## Shipping Methods
120
+
121
+ Shipping methods represent the carrier services available to customers (e.g., UPS Ground, FedEx Overnight, DHL International). Each shipping method is scoped to:
122
+
123
+ - **[Zones](/developer/core-concepts/addresses#zones)** — geographic regions where the method is available
124
+ - **Shipping Categories** — product groups the method handles
125
+ - **[Stores](/developer/core-concepts/stores)** — which stores offer this method
126
+
127
+ Only methods whose zone matches the customer's shipping address are offered at checkout.
128
+
129
+ ### Shipping Categories
130
+
131
+ Shipping categories group products with similar shipping requirements. For example:
132
+
133
+ - **Light** — lightweight items like stickers
134
+ - **Regular** — standard products
135
+ - **Heavy** — items over a certain weight
136
+ - **Oversized** — large items requiring special handling
137
+
138
+ Each product is assigned a shipping category. Shipping methods can be restricted to handle only certain categories, and the shipping cost calculator uses the category to determine pricing.
139
+
140
+ ### Calculators
141
+
142
+ Each shipping method uses a [Calculator](/developer/core-concepts/calculators) to determine the cost. Spree includes these built-in calculators:
143
+
144
+ | Calculator | Description |
145
+ |------------|-------------|
146
+ | Flat rate per order | Same cost regardless of items |
147
+ | Flat rate per item | Fixed cost per item |
148
+ | Flat percent | Percentage of the order total |
149
+ | Flexible rate | One rate for the first item, another for each additional |
150
+ | Price sack | Tiered pricing based on order total |
151
+
152
+ You can create custom calculators for more complex pricing. See the [Calculators guide](/developer/core-concepts/calculators).
153
+
154
+ ## Split Shipments
155
+
156
+ When items in an order ship from different stock locations or have different shipping categories, Spree automatically splits the order into multiple shipments.
157
+
158
+ ```mermaid
159
+ flowchart TB
160
+ A[Order with 3 items] --> B{Stock check}
161
+ B --> C["Item A & B: NYC Warehouse"]
162
+ B --> D["Item C: LA Warehouse"]
163
+ C --> E["Shipment 1: UPS Ground"]
164
+ D --> F["Shipment 2: FedEx 2Day"]
165
+ ```
166
+
167
+ ### How Splitting Works
168
+
169
+ 1. When an order reaches the delivery step, Spree evaluates where each item is in stock
170
+ 2. Items are grouped by stock location and shipping category
171
+ 3. Each group becomes a separate shipment with its own shipping rates
172
+ 4. The customer selects a shipping rate for each shipment independently
173
+
174
+ ### Weight Splitting
175
+
176
+ By default, Spree also splits shipments when a package exceeds a weight threshold (default: 150 units). This prevents individual packages from being too heavy.
177
+
178
+ > **INFO:** Split shipment behavior is customizable. See the [Customization Quickstart](/developer/customization/quickstart) for details on creating custom splitting rules.
179
+
180
+ ## Examples
181
+
182
+ ### Simple Setup
183
+
184
+ A store selling T-shirts to the US and Europe with 2 carriers:
185
+
186
+ | Method | Zone | Pricing |
187
+ |--------|------|---------|
188
+ | USPS Ground | US | $5 first item + $2 each additional |
189
+ | FedEx | EU | $10 per item |
190
+
191
+ This requires:
192
+ - 1 shipping category (default)
193
+ - 1 stock location
194
+ - 2 shipping methods with appropriate zones and calculators
195
+
196
+ ### Advanced Setup
197
+
198
+ A store shipping from 2 locations (New York, Los Angeles) with 3 carriers and 3 shipping categories:
199
+
200
+ | Category / Method | DHL | FedEx | USPS |
201
+ |:-|:-|:-|:-|
202
+ | Light | $5/item | $10 flat | $8/item |
203
+ | Regular | $5/item | $2/item | $8/item |
204
+ | Heavy | $50/item | $20 + $15/add'l | $20/item |
205
+
206
+ ## Related Documentation
207
+
208
+ - [Orders](/developer/core-concepts/orders) — Checkout flow and shipping rate selection
209
+ - [Inventory](/developer/core-concepts/inventory) — Stock locations and inventory management
210
+ - [Calculators](/developer/core-concepts/calculators) — Shipping rate calculators
211
+ - [Addresses](/developer/core-concepts/addresses) — Shipping address and zones
212
+ - [Events](/developer/core-concepts/events) — Subscribe to shipment events (e.g., `shipment.shipped`)
@@ -0,0 +1,111 @@
1
+ ---
2
+ title: Slugs
3
+ description: SEO-friendly URL identifiers for products, categories, and other resources
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Spree generates SEO-friendly URL slugs for resources like products, categories, and stores. Instead of accessing resources by ID, you can use clean, readable URLs based on resource names.
9
+
10
+ Both the Store API and Admin API accept slugs or IDs interchangeably for resource lookups.
11
+
12
+
13
+ ```typescript SDK
14
+ // Both work — slug or ID
15
+ const product = await client.products.get('spree-tote')
16
+ const product = await client.products.get('prod_86Rf07xd4z')
17
+
18
+ // Categories use permalink slugs
19
+ const category = await client.categories.get('clothing/shirts')
20
+ ```
21
+
22
+ ```bash cURL
23
+ # By slug
24
+ curl 'https://api.mystore.com/api/v3/store/products/spree-tote' \
25
+ -H 'Authorization: Bearer spree_pk_xxx'
26
+
27
+ # By ID
28
+ curl 'https://api.mystore.com/api/v3/store/products/prod_86Rf07xd4z' \
29
+ -H 'Authorization: Bearer spree_pk_xxx'
30
+ ```
31
+
32
+
33
+ ## Slug Generation
34
+
35
+ Slugs are automatically generated from resource names:
36
+
37
+ | Input | Generated Slug |
38
+ |-------|---------------|
39
+ | `Spree T-Shirt` | `spree-t-shirt` |
40
+ | `Café & Restaurant` | `cafe-and-restaurant` |
41
+ | `Summer Collection 2025` | `summer-collection-2025` |
42
+
43
+ If a slug already exists, Spree appends the SKU or a unique identifier to ensure uniqueness.
44
+
45
+ ## Models with Slugs
46
+
47
+ | Resource | Slug Column | Translatable | Hierarchical |
48
+ |----------|-------------|:---:|:---:|
49
+ | Product | `slug` | Yes | No |
50
+ | Category | `permalink` | Yes | Yes |
51
+ | Store | `code` | No | No |
52
+ | Post | `slug` | Yes | No |
53
+
54
+ ### Category Permalinks
55
+
56
+ Category slugs include the full parent path, making them hierarchical:
57
+
58
+ ```
59
+ clothing → "clothing"
60
+ clothing/shirts → "clothing/shirts"
61
+ clothing/shirts/t-shirts → "clothing/shirts/t-shirts"
62
+ ```
63
+
64
+ When a parent category is renamed, all child permalinks update automatically.
65
+
66
+ ## Slug History
67
+
68
+ When a slug changes (e.g., a product is renamed), Spree preserves the old slug. Requests using old slugs still find the resource, enabling:
69
+
70
+ - **SEO continuity** — no broken links when names change
71
+ - **Bookmark compatibility** — saved URLs keep working
72
+ - **Graceful URL migration** — old links resolve automatically
73
+
74
+ ## Internationalization
75
+
76
+ Products, categories, and posts support localized slugs — a different slug per locale:
77
+
78
+
79
+ ```typescript SDK
80
+ // English
81
+ const product = await client.products.get('red-shoes')
82
+
83
+ // French (with locale header)
84
+ const product = await client.products.get('chaussures-rouges', {
85
+ locale: 'fr',
86
+ })
87
+ ```
88
+
89
+ ```bash cURL
90
+ # English
91
+ curl 'https://api.mystore.com/api/v3/store/products/red-shoes' \
92
+ -H 'Authorization: Bearer spree_pk_xxx'
93
+
94
+ # French
95
+ curl 'https://api.mystore.com/api/v3/store/products/chaussures-rouges' \
96
+ -H 'Authorization: Bearer spree_pk_xxx' \
97
+ -H 'X-Spree-Locale: fr'
98
+ ```
99
+
100
+
101
+ Slugs are unique within the same locale but can be duplicated across different locales.
102
+
103
+ ## Reserved Words
104
+
105
+ Spree prevents certain words from being used as slugs to avoid route conflicts: `new`, `edit`, `index`, `login`, `logout`, `admin`, and others.
106
+
107
+ ## Related Documentation
108
+
109
+ - [Products](/developer/core-concepts/products) — Product catalog
110
+ - [Translations](/developer/core-concepts/translations) — Multi-language content
111
+ - [Querying](/api-reference/store-api/querying) — API resource lookup
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: Staff & Roles
3
+ description: Admin users, roles, invitations, and permissions
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Admin users manage the store via the Admin Panel. They have roles that control what they can access.
9
+
10
+ ```mermaid
11
+ erDiagram
12
+ AdminUser ||--o{ RoleUser : "has many"
13
+ RoleUser }o--|| Role : "belongs to"
14
+ RoleUser }o--|| Store : "scoped to"
15
+ AdminUser ||--o{ Invitation : "invites"
16
+
17
+ AdminUser {
18
+ string id
19
+ string email
20
+ }
21
+
22
+ RoleUser {
23
+ string role_id
24
+ string resource_type
25
+ string resource_id
26
+ }
27
+
28
+ Role {
29
+ string name
30
+ }
31
+
32
+ Invitation {
33
+ string email
34
+ string status
35
+ string token
36
+ datetime expires_at
37
+ }
38
+ ```
39
+
40
+ ## Roles
41
+
42
+ Admin users can have different roles that control their permissions:
43
+
44
+ | Role | Description |
45
+ |------|-------------|
46
+ | `admin` | Full access to all Admin Panel features |
47
+
48
+ > **INFO:** You can create custom roles with specific permissions. See the [Customize Permissions guide](/developer/customization/permissions) for details.
49
+
50
+ ## Creating Admin Users
51
+
52
+ Use the Spree CLI to create admin users:
53
+
54
+ ```bash
55
+ spree user create
56
+ ```
57
+
58
+ The CLI will prompt you for the email and password. You can also pass them directly:
59
+
60
+ ```bash
61
+ spree user create --email admin@example.com --password secret123
62
+ ```
63
+
64
+ The created user gets the `admin` role on the default store.
65
+
66
+ ## Inviting Admin Users
67
+
68
+ You can invite new admins through the Admin Panel or programmatically.
69
+
70
+ **Via Admin Panel:**
71
+
72
+ 1. Navigate to **Settings → Users**
73
+ 2. Click **Invite User**
74
+ 3. Enter the email address and select a role
75
+ 4. Click **Send Invitation**
76
+
77
+ The invitee receives an email with an invitation link. If they already have an account, they log in to accept. Otherwise, they create an account first.
78
+
79
+ ```mermaid
80
+ flowchart TB
81
+ A[Admin creates invitation] --> B[Invitation email sent]
82
+ B --> C[Invitee clicks link]
83
+ C --> D{Has account?}
84
+ D -->|Yes| E[Log in]
85
+ D -->|No| F[Create account]
86
+ E --> G[Accept invitation]
87
+ F --> G
88
+ G --> H[Role assigned to store]
89
+ ```
90
+
91
+ ### Invitation Details
92
+
93
+ | Attribute | Description |
94
+ |-----------|-------------|
95
+ | `email` | Invitee's email address |
96
+ | `token` | Secure token for the invitation link |
97
+ | `status` | `pending` or `accepted` |
98
+ | `expires_at` | Expiration date (default: 2 weeks) |
99
+ | `resource` | The store being granted access to |
100
+ | `role` | The role to assign upon acceptance |
101
+
102
+ ### Invitation Events
103
+
104
+ The invitation system publishes [events](/developer/core-concepts/events) you can subscribe to:
105
+
106
+ | Event | Description |
107
+ |-------|-------------|
108
+ | `invitation.created` | Invitation was created (triggers email) |
109
+ | `invitation.accepted` | Invitation was accepted and role assigned |
110
+ | `invitation.resent` | Invitation was resent to the invitee |
111
+
112
+ ## Permissions
113
+
114
+ Spree uses [CanCanCan](https://github.com/CanCanCommunity/cancancan) for authorization. Permissions apply to both customers (Store API access) and admins (Admin Panel access).
115
+
116
+ See the [Customize Permissions guide](/developer/customization/permissions) for details on creating custom roles and permission sets.
117
+
118
+ ## Related Documentation
119
+
120
+ - [Customers](/developer/core-concepts/customers) — Customer accounts and authentication
121
+ - [Stores](/developer/core-concepts/stores) — Multi-store setup
122
+ - [Permissions](/developer/customization/permissions) — Roles and authorization
123
+ - [Events](/developer/core-concepts/events) — Subscribe to invitation events