@spree/docs 0.1.177 → 0.1.178

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 (117) hide show
  1. package/dist/developer/cli/quickstart.md +1 -1
  2. package/dist/developer/contributing/creating-an-extension.md +2 -2
  3. package/dist/developer/core-concepts/addresses.md +3 -3
  4. package/dist/developer/core-concepts/architecture.md +4 -4
  5. package/dist/developer/core-concepts/calculators.md +2 -2
  6. package/dist/developer/core-concepts/carts.md +207 -0
  7. package/dist/developer/core-concepts/channels.md +3 -3
  8. package/dist/developer/core-concepts/customers.md +1 -1
  9. package/dist/developer/core-concepts/events.md +1 -1
  10. package/dist/developer/core-concepts/fulfillments.md +278 -0
  11. package/dist/developer/core-concepts/imports-exports.md +6 -18
  12. package/dist/developer/core-concepts/inventory.md +3 -3
  13. package/dist/developer/core-concepts/media.md +1 -1
  14. package/dist/developer/core-concepts/metafields.md +1 -1
  15. package/dist/developer/core-concepts/orders.md +92 -339
  16. package/dist/developer/core-concepts/payments.md +1 -1
  17. package/dist/developer/core-concepts/promotions.md +68 -195
  18. package/dist/developer/core-concepts/returns-exchanges-claims.md +173 -0
  19. package/dist/developer/core-concepts/store-credits-gift-cards.md +16 -18
  20. package/dist/developer/core-concepts/stores.md +1 -1
  21. package/dist/developer/core-concepts/taxes-discounts-fees.md +199 -0
  22. package/dist/developer/core-concepts/taxes.md +3 -3
  23. package/dist/developer/create-spree-app/quickstart.md +1 -1
  24. package/dist/developer/customization/api.md +36 -11
  25. package/dist/developer/customization/configuration.md +207 -37
  26. package/dist/developer/customization/decorators.md +8 -8
  27. package/dist/developer/customization/permissions.md +34 -229
  28. package/dist/developer/customization/quickstart.md +159 -108
  29. package/dist/developer/customization/validations.md +1 -1
  30. package/dist/developer/dashboard/overview.md +1 -1
  31. package/dist/developer/how-to/build-a-b2b-store.md +21 -0
  32. package/dist/developer/how-to/build-a-marketplace.md +25 -0
  33. package/dist/developer/how-to/custom-api-authentication.md +1 -1
  34. package/dist/developer/how-to/custom-delivery-rate-provider.md +242 -0
  35. package/dist/developer/how-to/custom-document-numbers.md +154 -0
  36. package/dist/developer/how-to/custom-order-routing.md +1 -1
  37. package/dist/developer/how-to/custom-payment-method.md +1 -1
  38. package/dist/developer/how-to/custom-promotion.md +76 -115
  39. package/dist/developer/how-to/custom-report.md +2 -2
  40. package/dist/developer/how-to/custom-stock-splitter.md +5 -5
  41. package/dist/developer/how-to/sell-digital-products.md +20 -0
  42. package/dist/developer/multi-tenant/quickstart.md +1 -1
  43. package/dist/developer/providers/dam.md +14 -0
  44. package/dist/developer/providers/erp.md +31 -0
  45. package/dist/developer/providers/fulfillment.md +25 -0
  46. package/dist/developer/{deployment/telemetry.md → providers/observability.md} +1 -1
  47. package/dist/developer/providers/overview.md +44 -0
  48. package/dist/developer/providers/pim.md +25 -0
  49. package/dist/developer/providers/sso.md +20 -0
  50. package/dist/developer/sdk/admin/extending.md +1 -1
  51. package/dist/developer/sdk/admin/quickstart.md +1 -1
  52. package/dist/developer/sdk/admin/resources.md +1 -1
  53. package/dist/developer/sdk/extending.md +1 -1
  54. package/dist/developer/tutorial/admin-api.md +13 -0
  55. package/dist/developer/tutorial/dashboard-plugin.md +14 -0
  56. package/dist/developer/tutorial/events.md +7 -161
  57. package/dist/developer/tutorial/introduction.md +15 -35
  58. package/dist/developer/tutorial/model.md +7 -98
  59. package/dist/developer/tutorial/store-api.md +13 -0
  60. package/dist/developer/tutorial/storefront.md +12 -0
  61. package/dist/developer/tutorial/testing.md +7 -711
  62. package/dist/developer/upgrades/5.6-to-6.0.md +2 -2
  63. package/package.json +1 -1
  64. package/dist/developer/admin/admin.md +0 -214
  65. package/dist/developer/admin/authentication.md +0 -59
  66. package/dist/developer/admin/components.md +0 -711
  67. package/dist/developer/admin/custom-css.md +0 -256
  68. package/dist/developer/admin/custom-javascript.md +0 -116
  69. package/dist/developer/admin/extending-ui.md +0 -1839
  70. package/dist/developer/admin/form-builder.md +0 -444
  71. package/dist/developer/admin/helper-methods.md +0 -531
  72. package/dist/developer/admin/navigation.md +0 -805
  73. package/dist/developer/admin/tables.md +0 -490
  74. package/dist/developer/advanced/adding_spree_to_rails_app.md +0 -92
  75. package/dist/developer/core-concepts/adjustments.md +0 -113
  76. package/dist/developer/core-concepts/reports.md +0 -208
  77. package/dist/developer/core-concepts/shipments.md +0 -307
  78. package/dist/developer/core-concepts/users.md +0 -303
  79. package/dist/developer/customization/authentication.md +0 -100
  80. package/dist/developer/customization/checkout.md +0 -202
  81. package/dist/developer/customization/emails.md +0 -18
  82. package/dist/developer/customization/routes.md +0 -24
  83. package/dist/developer/multi-vendor/installation.md +0 -61
  84. package/dist/developer/multi-vendor/quickstart.md +0 -17
  85. package/dist/developer/tutorial/admin.md +0 -206
  86. package/dist/developer/tutorial/api.md +0 -606
  87. package/dist/developer/tutorial/extending-models.md +0 -393
  88. package/dist/developer/tutorial/sdk.md +0 -170
  89. package/dist/developer/upgrades/2.0-to-2.1.md +0 -46
  90. package/dist/developer/upgrades/2.1-to-2.2.md +0 -59
  91. package/dist/developer/upgrades/2.2-to-2.3.md +0 -44
  92. package/dist/developer/upgrades/2.3-to-2.4.md +0 -42
  93. package/dist/developer/upgrades/3.0-to-3.1.md +0 -47
  94. package/dist/developer/upgrades/3.1-to-3.2.md +0 -34
  95. package/dist/developer/upgrades/3.2-to-3.3.md +0 -70
  96. package/dist/developer/upgrades/3.3-to-3.4.md +0 -36
  97. package/dist/developer/upgrades/3.4-to-3.5.md +0 -44
  98. package/dist/developer/upgrades/3.5-to-3.6.md +0 -40
  99. package/dist/developer/upgrades/3.6-to-3.7.md +0 -62
  100. package/dist/developer/upgrades/3.7-to-4.0.md +0 -152
  101. package/dist/developer/upgrades/4.0-to-4.1.md +0 -92
  102. package/dist/developer/upgrades/4.1-to-4.2.md +0 -109
  103. package/dist/developer/upgrades/4.10-to-5.0.md +0 -131
  104. package/dist/developer/upgrades/4.2-to-4.3.md +0 -100
  105. package/dist/developer/upgrades/4.3-to-4.4.md +0 -125
  106. package/dist/developer/upgrades/4.4-to-4.5.md +0 -94
  107. package/dist/developer/upgrades/4.5-to-4.6.md +0 -119
  108. package/dist/developer/upgrades/4.6-to-4.7.md +0 -39
  109. package/dist/developer/upgrades/4.8-to-4.9.md +0 -24
  110. package/dist/developer/upgrades/4.9-to-4.10.md +0 -24
  111. package/dist/developer/upgrades/4.x-to-4.8.md +0 -52
  112. package/dist/developer/upgrades/5.0-to-5.1.md +0 -28
  113. package/dist/developer/upgrades/5.1-to-5.2.md +0 -131
  114. package/dist/developer/upgrades/5.2-to-5.3.md +0 -338
  115. package/dist/developer/upgrades/5.3-to-5.4.md +0 -277
  116. package/dist/developer/upgrades/5.4-to-5.5.md +0 -301
  117. package/dist/developer/upgrades/5.5-to-5.6.md +0 -207
@@ -1,393 +0,0 @@
1
- ---
2
- title: Extending Core Models
3
- description: Tutorial — extend Spree's core models with a custom Brand resource, generate a migration, and associate it with Products via a decorator.
4
- ---
5
-
6
- > **NOTE:** This is a backend customization. You need to perform it in the `backend` directory if you used `create-spree-app` to set up your Spree application.
7
-
8
- In this tutorial, we'll connect our custom Brand model with Spree's core Product model. This is a common pattern when building features that need to integrate with existing Spree functionality.
9
-
10
- > **INFO:** This guide assumes you've completed the [Model](model.md) and [Admin](admin.md) tutorials.
11
-
12
- ## What We're Building
13
-
14
- By the end of this tutorial, you'll have:
15
-
16
- - Products associated with Brands
17
- - A brand selector in the Product admin form
18
- - Understanding of how to safely extend Spree core models
19
-
20
- ## Choosing the Right Approach
21
-
22
- Before extending Spree models, consider which approach fits your needs best:
23
-
24
- | What you need | Recommended approach |
25
- |---------------|---------------------|
26
- | Add association (belongs_to, has_many) | **Decorator** (this tutorial) |
27
- | Add validation or scope | **Decorator** |
28
- | Add new instance/class method | **Decorator** |
29
- | React to model changes (after save, etc.) | [Events subscriber](../core-concepts/events.md) |
30
- | Sync with external service on changes | [Events](../core-concepts/events.md) or [Webhooks](../core-concepts/webhooks.md) |
31
- | Add searchable/filterable field | [Ransack configuration](../core-concepts/search-filtering.md#extending-ransackable-configuration) |
32
- | Add admin UI elements | [Admin Partials](../admin/extending-ui.md) |
33
-
34
- > **INFO:** This tutorial uses **decorators** because we're adding a structural association between models. For behavioral changes like callbacks, prefer [Events](../core-concepts/events.md) instead - they're easier to test and maintain.
35
-
36
- ## Understanding Decorators
37
-
38
- When working with Spree, you'll often need to add functionality to existing models like `Spree::Product` or `Spree::Order`. However, you shouldn't modify these files directly because:
39
-
40
- 1. **Upgrades** - Your changes would be lost when updating Spree
41
- 2. **Maintainability** - It's hard to track what you've customized
42
- 3. **Conflicts** - Direct modifications can conflict with Spree's code
43
-
44
- Instead, we use **decorators** - a Ruby pattern that lets you add or modify behavior of existing classes without changing their original source code.
45
-
46
- ### How Decorators Work
47
-
48
- In Ruby, classes are "open" - you can add methods to them at any time. Decorators leverage this by:
49
-
50
- 1. Creating a module with your new methods
51
- 2. Using `Module#prepend` to inject your module into the class's inheritance chain
52
- 3. Your methods run first, and can call `super` to invoke the original method
53
-
54
- ```ruby
55
- # This is the basic pattern
56
- module Spree
57
- module ProductDecorator
58
- # Add a new method
59
- def my_new_method
60
- "Hello from decorator!"
61
- end
62
-
63
- # Override an existing method
64
- def existing_method
65
- # Do something before
66
- result = super # Call the original method
67
- # Do something after
68
- result
69
- end
70
- end
71
-
72
- Product.prepend(ProductDecorator)
73
- end
74
- ```
75
-
76
- The key line is `Product.prepend(ProductDecorator)` - this inserts your module at the beginning of the method lookup chain, so your methods are found first.
77
-
78
- ## Step 1: Create the Migration
79
-
80
- First, add a `brand_id` column to the products table:
81
-
82
-
83
- ```bash Spree CLI (Docker)
84
- spree generate migration AddBrandIdToSpreeProducts brand_id:integer:index
85
- ```
86
-
87
- ```bash Without Spree CLI
88
- bin/rails g migration AddBrandIdToSpreeProducts brand_id:integer:index
89
- ```
90
-
91
-
92
- Edit the migration to add an index (but no foreign key constraint, keeping it optional):
93
-
94
- ```ruby db/migrate/XXXXXXXXXXXXXX_add_brand_id_to_spree_products.rb
95
- class AddBrandIdToSpreeProducts < ActiveRecord::Migration[8.0]
96
- def change
97
- add_column :spree_products, :brand_id, :integer
98
- add_index :spree_products, :brand_id
99
- end
100
- end
101
- ```
102
-
103
- Run the migration:
104
-
105
-
106
- ```bash Spree CLI (Docker)
107
- spree migrate
108
- ```
109
-
110
- ```bash Without Spree CLI
111
- bin/rails db:migrate
112
- ```
113
-
114
-
115
- > **INFO:** We intentionally don't add a foreign key constraint. This keeps the association optional and avoids issues if brands are deleted. Spree follows this pattern for flexibility.
116
-
117
- ## Step 2: Generate the Product Decorator
118
-
119
- Spree provides a generator to create decorator files with the correct structure:
120
-
121
-
122
- ```bash Spree CLI (Docker)
123
- spree generate model_decorator Spree::Product
124
- ```
125
-
126
- ```bash Without Spree CLI
127
- bin/rails g spree:model_decorator Spree::Product
128
- ```
129
-
130
-
131
- This creates `app/models/spree/product_decorator.rb`:
132
-
133
- ```ruby app/models/spree/product_decorator.rb
134
- module Spree
135
- module ProductDecorator
136
- def self.prepended(base)
137
- # Class-level configurations go here
138
- end
139
- end
140
-
141
- Product.prepend(ProductDecorator)
142
- end
143
- ```
144
-
145
- ## Step 3: Add the Brand Association to Product
146
-
147
- Update the decorator to add the `belongs_to` association:
148
-
149
- ```ruby app/models/spree/product_decorator.rb {4}
150
- module Spree
151
- module ProductDecorator
152
- def self.prepended(base)
153
- base.belongs_to :brand, class_name: 'Spree::Brand', optional: true
154
- end
155
- end
156
-
157
- Product.prepend(ProductDecorator)
158
- end
159
- ```
160
-
161
- ### Understanding the Code
162
-
163
- - `self.prepended(base)` - This callback runs when the module is prepended to a class. The `base` parameter is the class being decorated (`Spree::Product`)
164
- - `base.belongs_to` - We call class methods on `base` to add associations, validations, scopes, etc.
165
- - `optional: true` - Products don't require a brand (the `brand_id` can be `NULL`)
166
-
167
- ## Step 4: Add Products Association to Brand
168
-
169
- Now update your Brand model to define the reverse association:
170
-
171
- ```ruby app/models/spree/brand.rb {5}
172
- module Spree
173
- class Brand < Spree::Base
174
- # ... existing code ...
175
-
176
- has_many :products, class_name: 'Spree::Product', dependent: :nullify
177
-
178
- # ... rest of your model ...
179
- end
180
- end
181
- ```
182
-
183
- > **INFO:** We use `dependent: :nullify` instead of `dependent: :destroy`. When a brand is deleted, products will have their `brand_id` set to `NULL` rather than being deleted. This is safer for e-commerce data.
184
-
185
- ## Step 5: Permit the Brand Parameter
186
-
187
- For the admin form to save the brand association, we need to permit the `brand_id` parameter.
188
-
189
- Add to your Spree initializer:
190
-
191
- ```ruby config/initializers/spree.rb {3}
192
- # .. other code ..
193
-
194
- Spree::PermittedAttributes.product_attributes << :brand_id
195
- ```
196
-
197
- ## Step 6: Add Brand Selector to Product Admin Form
198
-
199
- Create a partial to inject the brand selector into the product form. Spree's admin product form has injection points for customization.
200
-
201
- Create the partial:
202
-
203
- ```erb app/views/spree/admin/products/_brand_field.html.erb
204
- <div class="card mb-6">
205
- <div class="card-header">
206
- <h5 class="card-title"><%= Spree.t(:brand) %></h5>
207
- </div>
208
- <div class="card-body">
209
- <%= f.spree_select :brand_id,
210
- Spree::Brand.order(:name).pluck(:name, :id),
211
- { include_blank: true, label: Spree.t(:brand) } %>
212
- </div>
213
- ```
214
-
215
- Register this partial to appear in the product form. Add to your initializer:
216
-
217
- **Spree 5.2+:**
218
-
219
- ```ruby config/initializers/spree.rb
220
- Rails.application.config.after_initialize do
221
- Spree.admin.partials.product_form_sidebar << 'spree/admin/products/brand_field'
222
- end
223
- ```
224
-
225
- **Spree 5.1 and below:**
226
-
227
- ```ruby config/initializers/spree.rb
228
- Rails.application.config.spree_admin.product_form_sidebar_partials << 'spree/admin/products/brand_field'
229
- ```
230
-
231
-
232
- ## Step 7: Add Translation
233
-
234
- Add the translation for the brand label:
235
-
236
- ```yaml config/locales/en.yml
237
- en:
238
- spree:
239
- brand: Brand
240
- ```
241
-
242
- ## Testing the Association
243
-
244
- Verify everything works in the Rails console:
245
-
246
- ```ruby
247
- # Create a brand and product
248
- brand = Spree::Brand.create!(name: 'Nike')
249
- product = Spree::Product.first
250
- product.update!(brand: brand)
251
-
252
- # Test associations
253
- product.brand # => #<Spree::Brand id: 1, name: "Nike"...>
254
- brand.products # => [#<Spree::Product...>]
255
- brand.products.count # => 1
256
- ```
257
-
258
- ## Decorator Best Practices
259
-
260
-
261
- - **Use prepended callback** — Always use `self.prepended(base)` for class-level additions like associations, validations, and scopes.
262
-
263
- - **Keep decorators focused** — Each decorator should have a single responsibility. Create multiple decorators if needed.
264
-
265
- - **Call super when overriding** — When overriding methods, call `super` to preserve original behavior unless you intentionally want to replace it.
266
-
267
- - **Test decorated behavior** — Write tests specifically for your decorated functionality to catch regressions.
268
-
269
-
270
- ### Common Decorator Patterns
271
-
272
- #### Adding Validations
273
-
274
- ```ruby
275
- def self.prepended(base)
276
- base.validates :custom_field, presence: true
277
- end
278
- ```
279
-
280
- #### Adding Scopes
281
-
282
- ```ruby
283
- def self.prepended(base)
284
- base.scope :featured, -> { where(featured: true) }
285
- end
286
- ```
287
-
288
- #### Adding Callbacks
289
-
290
- > **WARNING:** For callbacks that trigger side effects (syncing to external services, sending notifications, etc.), use [Events subscribers](../core-concepts/events.md) instead of decorator callbacks. Events are easier to test and won't break during Spree upgrades.
291
-
292
- **Decorator approach** (use only for simple, internal logic):
293
-
294
- ```ruby
295
- def self.prepended(base)
296
- base.before_save :normalize_name
297
- end
298
-
299
- def normalize_name
300
- self.name = name.strip.titleize if name.present?
301
- end
302
- ```
303
-
304
- **Events approach** (recommended for side effects): subscribe to `product.updated` and react in a `Spree::Subscriber` — no decorator, no callback coupling. The [Events & Webhooks tutorial](events.md) builds this out fully, including external-system sync (OMS, warehouse) and outbound webhooks.
305
-
306
- #### Adding Class Methods
307
-
308
- ```ruby
309
- def self.prepended(base)
310
- base.extend ClassMethods
311
- end
312
-
313
- module ClassMethods
314
- def my_class_method
315
- # Class method logic
316
- end
317
- end
318
- ```
319
-
320
- ## Complete Files
321
-
322
- ### Product Decorator
323
-
324
- ```ruby app/models/spree/product_decorator.rb
325
- module Spree
326
- module ProductDecorator
327
- def self.prepended(base)
328
- base.belongs_to :brand, class_name: 'Spree::Brand', optional: true
329
- end
330
- end
331
-
332
- Product.prepend(ProductDecorator)
333
- end
334
- ```
335
-
336
- ### Brand Model (Updated)
337
-
338
- ```ruby app/models/spree/brand.rb
339
- module Spree
340
- class Brand < Spree::Base
341
- has_many :products, class_name: 'Spree::Product', dependent: :nullify
342
-
343
- has_one_attached :logo
344
- has_rich_text :description
345
-
346
- validates :name, presence: true
347
- end
348
- end
349
- ```
350
-
351
- > **INFO:** SEO features like slugs, meta titles, and FriendlyId are covered in the [Slugs](../core-concepts/slugs.md) documentation.
352
-
353
- ### Spree Initializer Additions
354
-
355
- ```ruby config/initializers/spree.rb
356
- # Permit brand_id in product params
357
- Spree::PermittedAttributes.product_attributes << :brand_id
358
- ```
359
-
360
- **Spree 5.2+:**
361
-
362
- ```ruby config/initializers/spree.rb
363
- Rails.application.config.after_initialize do
364
- # Add brand field to product form
365
- Spree.admin.partials.product_form << 'spree/admin/products/brand_field'
366
- end
367
- ```
368
-
369
- **Spree 5.1 and below:**
370
-
371
- ```ruby config/initializers/spree.rb
372
- # Add brand field to product form
373
- Rails.application.config.spree_admin.product_form_partials << 'spree/admin/products/brand_field'
374
- ```
375
-
376
-
377
- ## Next Step
378
-
379
- Now that Brands are connected to Products, let's expose them through the Store API:
380
-
381
- - [6. API](api.md) — Create API endpoints for brands and extend the Product API response
382
-
383
- ## Related Documentation
384
-
385
- - [Model Tutorial](model.md) - Creating the Brand model
386
- - [Admin Tutorial](admin.md) - Building the admin interface
387
- - [API Tutorial](api.md) - Exposing brands through the API
388
- - [Events & Webhooks tutorial](events.md) - Subscribers, custom events, and webhooks in the Brand storyline
389
- - [Events](../core-concepts/events.md) - Subscribe to model changes without decorators
390
- - [Webhooks](../core-concepts/webhooks.md) - HTTP callbacks for external integrations
391
- - [Decorators](../customization/decorators.md) - Full decorator reference
392
- - [Customization Overview](../customization/quickstart.md) - More customization patterns
393
- - [Products](../core-concepts/products.md) - Product model documentation
@@ -1,170 +0,0 @@
1
- ---
2
- title: SDK
3
- description: Use the Spree TypeScript SDK to consume your custom Brand endpoints, fetch extended Product data, and surface the new resource in your headless storefront.
4
- ---
5
-
6
- In this tutorial, we'll use the `@spree/sdk` TypeScript SDK to consume the Brand API endpoints we created in the [API tutorial](api.md), and work with the extended Product data that now includes brand information.
7
-
8
- > **INFO:** This guide assumes you've completed the [API](api.md) tutorial and have the Brand endpoints running.
9
-
10
- ## What We're Building
11
-
12
- By the end of this tutorial, you'll have:
13
-
14
- - Typed calls to your custom Brand endpoints using `client.request`
15
- - Extended Product types that include brand data
16
- - A working brand page example that ties it all together
17
-
18
- ## How the SDK Works
19
-
20
- The `@spree/sdk` package provides a typed client for the Store API:
21
-
22
- ```typescript
23
- import { createClient } from '@spree/sdk'
24
-
25
- const client = createClient({
26
- baseUrl: 'https://api.mystore.com',
27
- publishableKey: 'pk_YOUR_KEY',
28
- })
29
-
30
- // Built-in resources
31
- const products = await client.products.list()
32
- const product = await client.products.get('prod_86Rf07xd4z')
33
- const cart = await client.carts.create()
34
- ```
35
-
36
- Under the hood, `createClient()` creates a request function that handles auth headers (`x-spree-api-key`), retries with exponential backoff, and URL building. All requests go through the base path `/api/v3/store`, so `client.products.list()` calls `GET /api/v3/store/products`.
37
-
38
- ## Calling Custom Endpoints
39
-
40
- The client exposes a `request` method — the same function that powers all built-in resources. Use it to call any Store API endpoint, including custom ones:
41
-
42
- ```typescript
43
- import { createClient } from '@spree/sdk'
44
- import type { PaginatedResponse } from '@spree/sdk'
45
-
46
- const client = createClient({
47
- baseUrl: 'https://api.mystore.com',
48
- publishableKey: 'pk_YOUR_KEY',
49
- })
50
-
51
- // Define your Brand type
52
- interface Brand {
53
- id: string
54
- name: string
55
- slug: string | null
56
- description: string | null
57
- logo_url: string | null
58
- }
59
-
60
- // Call custom endpoints — paths are relative to /api/v3/store
61
- const brands = await client.request<PaginatedResponse<Brand>>('GET', '/brands')
62
- const nike = await client.request<Brand>('GET', '/brands/nike')
63
- ```
64
-
65
- `client.request` has the same auth headers, retry logic, and locale/currency defaults as all built-in resources. The type parameter (`<Brand>`, `<PaginatedResponse<Brand>>`) gives you full type safety on the response.
66
-
67
- ## Step 1: Define Brand Types
68
-
69
- Create a types file for your custom Brand resource:
70
-
71
- ```typescript types/brand.ts
72
- import type { Product, PaginatedResponse } from '@spree/sdk'
73
-
74
- export interface Brand {
75
- id: string
76
- name: string
77
- slug: string | null
78
- description: string | null
79
- logo_url: string | null
80
- }
81
-
82
- export interface ProductWithBrand extends Product {
83
- brand_id: string | null
84
- brand?: Brand
85
- }
86
- ```
87
-
88
- ## Step 2: Work with Extended Product Responses
89
-
90
- The Product serializer now includes `brand_id` and an expandable `brand` association.
91
-
92
- ### Fetching Products with Brand Data
93
-
94
- ```typescript
95
- import type { ProductWithBrand } from './types/brand'
96
-
97
- // Without expand — brand_id is included, brand object is not
98
- const product = await client.products.get('prod_86Rf07xd4z') as ProductWithBrand
99
- console.log(product.brand_id) // "brand_k5nR8xLq"
100
- console.log(product.brand) // undefined
101
-
102
- // With expand — full brand object included
103
- const productWithBrand = await client.products.get(
104
- 'prod_86Rf07xd4z',
105
- { expand: ['brand'] }
106
- ) as ProductWithBrand
107
- console.log(productWithBrand.brand?.name) // "Nike"
108
-
109
- // Multiple expands
110
- const full = await client.products.get(
111
- 'prod_86Rf07xd4z',
112
- { expand: ['brand', 'variants', 'categories'] }
113
- ) as ProductWithBrand
114
- ```
115
-
116
- ### Filtering Products by Brand
117
-
118
- Ransack predicates work on whitelisted attributes and associations. The [API tutorial](api.md) shows how to register `brand_id` and `brand` via `Spree.ransack` — once that's done, you can filter:
119
-
120
- ```typescript
121
- // Products from a specific brand
122
- const nikeProducts = await client.products.list({
123
- brand_id_eq: 'brand_k5nR8xLq',
124
- })
125
-
126
- // Products matching brand name (requires Spree.ransack.add_association)
127
- const nikeProducts2 = await client.products.list({
128
- brand_name_cont: 'nike',
129
- })
130
- ```
131
-
132
- > **INFO:** Ransack predicates like `_eq`, `_cont`, `_gt`, `_lt` work on whitelisted attributes and associations. See [Search & Filtering](../core-concepts/search-filtering.md) for the full list.
133
-
134
- ## Complete Example: Brand Page
135
-
136
- A real-world example combining everything — fetch a brand by slug and list its products:
137
-
138
- ```typescript
139
- import { createClient } from '@spree/sdk'
140
- import type { PaginatedResponse } from '@spree/sdk'
141
- import type { Brand, ProductWithBrand } from './types/brand'
142
-
143
- const client = createClient({
144
- baseUrl: 'https://api.mystore.com',
145
- publishableKey: 'pk_YOUR_KEY',
146
- })
147
-
148
- // Fetch brand by slug
149
- const brand = await client.request<Brand>('GET', '/brands/nike')
150
-
151
- // Fetch products for this brand
152
- const products = await client.products.list({
153
- brand_id_eq: brand.id,
154
- sort: '-available_on',
155
- }) as PaginatedResponse<ProductWithBrand>
156
-
157
- // Render
158
- console.log(`${brand.name} — ${brand.description}`)
159
- console.log(`${products.meta.count} products`)
160
- products.data.forEach(p => {
161
- console.log(` ${p.name} — ${p.price.display}`)
162
- })
163
- ```
164
-
165
- ## Related Documentation
166
-
167
- - [API Tutorial](api.md) - Creating the Brand API endpoints
168
- - [SDK Overview](/sdk) - Full SDK documentation
169
- - [Search & Filtering](../core-concepts/search-filtering.md) - Ransack predicates and sorting
170
- - [Agentic Development](../agentic/overview.md) - Agent skills and the docs MCP server cover the SDK patterns used here
@@ -1,46 +0,0 @@
1
- ---
2
- title: 2.0 to 2.1
3
- description: 'This guide covers upgrading a 2.0 Spree store, to a 2.1 store.'
4
- ---
5
-
6
- ## Overview
7
-
8
- This guide has been written from the perspective of a blank Spree 2.0 store with no extensions.
9
-
10
- If you have extensions that your store depends on, you will need to manually verify that each of those extensions works within your 2.1 store once this upgrade is complete. Typically, extensions that are compatible with this version of Spree will have a 2-1-stable branch.
11
-
12
- This is the first Spree release that supports Rails 4 exclusively. Spree releases after this point will continue to support Rails 4 only.
13
-
14
- ## Upgrade Rails
15
-
16
- For this Spree release, you will need to upgrade your Rails version to at least 4.0.0.
17
-
18
- It is recommended to read through the [Upgrading Ruby on Rails guide](http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-%20from-rails-3-2-to-rails-4-0) to learn what needs to be done for your application to migrate to Rails 4.
19
-
20
- ```ruby
21
- gem 'rails', '~> 4.0'
22
- ```
23
-
24
- ## Upgrade Spree
25
-
26
- For best results, use the 2-1-stable branch from GitHub:
27
-
28
- ```ruby
29
- gem 'spree', '~> 2.1'
30
- ```
31
-
32
- Run `bundle update spree`.
33
-
34
- ## Copy and run migrations
35
-
36
- Copy over the migrations from Spree (and any other engine) and run them using
37
- these commands:
38
-
39
- ```bash
40
- rake railties:install:migrations
41
- rake db:migrate
42
- ```
43
-
44
- ## Read the release notes
45
-
46
- For information about changes contained with this release, please read the [2.1.0 Release Notes](https://github.com/spree/spree/releases/tag/v2.1.0).
@@ -1,59 +0,0 @@
1
- ---
2
- title: 2.1 to 2.2
3
- section: upgrades
4
- description: 'This guide covers upgrading a 2.1 Spree store, to a 2.2 store.'
5
- ---
6
-
7
- ## Overview
8
-
9
- This guide has been written from the perspective of a blank Spree 2.1 store with no extensions.
10
-
11
- If you have extensions that your store depends on, you will need to manually verify that each of those extensions works within your 2.2 store once this upgrade is complete. Typically, extensions that are compatible with this version of Spree will have a 2-2-stable branch.
12
-
13
- ## Upgrade Rails
14
-
15
- For this Spree release, you will need to upgrade your Rails version to at least 4.0.6.
16
-
17
- ```ruby
18
- gem 'rails', '~> 4.0.6'
19
- ```
20
-
21
- ## Upgrade Spree
22
-
23
- For best results, use the 2-2-stable branch from GitHub:
24
-
25
- ```ruby
26
- gem 'spree', '~> 2.2'
27
- ```
28
-
29
- Run `bundle update spree`.
30
-
31
- ## Copy and run migrations
32
-
33
- Copy over the migrations from Spree (and any other engine) and run them using
34
- these commands:
35
-
36
- ```bash
37
- rake railties:install:migrations
38
- ```
39
-
40
- ```bash
41
- rake db:migrate
42
- ```
43
-
44
- ## Read the release notes
45
-
46
- For information about changes contained with this release, please read the [2.2.0 Release Notes](http://guides.spreecommerce.org/release_notes/spree_2_2_0.html).
47
-
48
- ### Rename assets
49
-
50
- As mentioned in the release notes, asset paths have changed. Change the references on the left, to the ones on the right:
51
-
52
- * `admin/spree_backend` => `spree/backend`
53
- * `store/spree_frontend` => `spree/frontend`
54
-
55
- This applies across the board on Spree, and may need to be done in your store's extensions.
56
-
57
- ### Paperclip settings have been removed from master
58
-
59
- Please consult [this section](http://guides.spreecommerce.org/release_notes/spree_2_2_0.html#paperclip-settings-have-been-removed) of the release notes if you were using custom Paperclip settings. This will direct you what to do in that particular case.