@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.
- package/README.md +54 -0
- package/dist/api-reference/platform/authentication.md +38 -0
- package/dist/api-reference/store-api/authentication.md +188 -0
- package/dist/api-reference/store-api/errors.md +277 -0
- package/dist/api-reference/store-api/idempotency.md +129 -0
- package/dist/api-reference/store-api/introduction.md +34 -0
- package/dist/api-reference/store-api/localization.md +279 -0
- package/dist/api-reference/store-api/metadata.md +160 -0
- package/dist/api-reference/store-api/monetary-amounts.md +65 -0
- package/dist/api-reference/store-api/querying.md +399 -0
- package/dist/api-reference/store-api/rate-limitting.md +103 -0
- package/dist/api-reference/store-api/relations.md +185 -0
- package/dist/api-reference/storefront/authentication.md +88 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
- package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
- package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
- package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
- package/dist/api-reference/v2/introduction.md +22 -0
- package/dist/api-reference/v2/pagination.md +37 -0
- package/dist/api-reference/webhooks-events.md +883 -0
- package/dist/developer/admin/admin.md +205 -0
- package/dist/developer/admin/authentication.md +59 -0
- package/dist/developer/admin/components.md +711 -0
- package/dist/developer/admin/custom-css.md +243 -0
- package/dist/developer/admin/custom-javascript.md +116 -0
- package/dist/developer/admin/extending-ui.md +1964 -0
- package/dist/developer/admin/form-builder.md +444 -0
- package/dist/developer/admin/helper-methods.md +531 -0
- package/dist/developer/admin/navigation.md +805 -0
- package/dist/developer/admin/tables.md +491 -0
- package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
- package/dist/developer/cli/quickstart.md +137 -0
- package/dist/developer/contributing/creating-an-extension.md +258 -0
- package/dist/developer/contributing/developing-spree.md +339 -0
- package/dist/developer/contributing/quickstart.md +32 -0
- package/dist/developer/contributing/updating-extensions.md +67 -0
- package/dist/developer/core-concepts/addresses.md +265 -0
- package/dist/developer/core-concepts/adjustments.md +107 -0
- package/dist/developer/core-concepts/architecture.md +177 -0
- package/dist/developer/core-concepts/calculators.md +323 -0
- package/dist/developer/core-concepts/customers.md +230 -0
- package/dist/developer/core-concepts/events.md +624 -0
- package/dist/developer/core-concepts/imports-exports.md +698 -0
- package/dist/developer/core-concepts/inventory.md +191 -0
- package/dist/developer/core-concepts/markets.md +250 -0
- package/dist/developer/core-concepts/media.md +167 -0
- package/dist/developer/core-concepts/metafields.md +187 -0
- package/dist/developer/core-concepts/orders.md +328 -0
- package/dist/developer/core-concepts/payments.md +710 -0
- package/dist/developer/core-concepts/pricing.md +163 -0
- package/dist/developer/core-concepts/products.md +360 -0
- package/dist/developer/core-concepts/promotions.md +322 -0
- package/dist/developer/core-concepts/reports.md +206 -0
- package/dist/developer/core-concepts/search-filtering.md +237 -0
- package/dist/developer/core-concepts/shipments.md +212 -0
- package/dist/developer/core-concepts/slugs.md +111 -0
- package/dist/developer/core-concepts/staff-roles.md +123 -0
- package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
- package/dist/developer/core-concepts/stores.md +117 -0
- package/dist/developer/core-concepts/taxes.md +135 -0
- package/dist/developer/core-concepts/translations.md +120 -0
- package/dist/developer/core-concepts/users.md +299 -0
- package/dist/developer/core-concepts/webhooks.md +378 -0
- package/dist/developer/create-spree-app/quickstart.md +158 -0
- package/dist/developer/customization/api.md +93 -0
- package/dist/developer/customization/authentication.md +88 -0
- package/dist/developer/customization/checkout.md +204 -0
- package/dist/developer/customization/configuration.md +55 -0
- package/dist/developer/customization/decorators.md +523 -0
- package/dist/developer/customization/dependencies.md +232 -0
- package/dist/developer/customization/emails.md +21 -0
- package/dist/developer/customization/extensions.md +92 -0
- package/dist/developer/customization/metadata.md +236 -0
- package/dist/developer/customization/model-preferences.md +130 -0
- package/dist/developer/customization/permissions.md +265 -0
- package/dist/developer/customization/quickstart.md +229 -0
- package/dist/developer/customization/routes.md +24 -0
- package/dist/developer/customization/v4/admin-panel.md +78 -0
- package/dist/developer/customization/v4/authentication.md +210 -0
- package/dist/developer/customization/v4/checkout.md +212 -0
- package/dist/developer/customization/v4/deface.md +251 -0
- package/dist/developer/customization/v4/images.md +86 -0
- package/dist/developer/customization/v4/storefront.md +450 -0
- package/dist/developer/deployment/assets.md +87 -0
- package/dist/developer/deployment/aws.md +335 -0
- package/dist/developer/deployment/caching.md +27 -0
- package/dist/developer/deployment/cdn.md +39 -0
- package/dist/developer/deployment/database.md +155 -0
- package/dist/developer/deployment/docker.md +128 -0
- package/dist/developer/deployment/emails.md +77 -0
- package/dist/developer/deployment/environment_variables.md +111 -0
- package/dist/developer/deployment/heroku.md +51 -0
- package/dist/developer/deployment/render.md +95 -0
- package/dist/developer/getting-started/quickstart.md +82 -0
- package/dist/developer/how-to/custom-payment-method.md +374 -0
- package/dist/developer/how-to/custom-promotion.md +373 -0
- package/dist/developer/how-to/custom-report.md +387 -0
- package/dist/developer/how-to/custom-search-provider.md +230 -0
- package/dist/developer/multi-store/quickstart.md +71 -0
- package/dist/developer/multi-store/setup.md +38 -0
- package/dist/developer/multi-tenant/configuration.md +41 -0
- package/dist/developer/multi-tenant/core-concepts.md +75 -0
- package/dist/developer/multi-tenant/installation.md +96 -0
- package/dist/developer/multi-tenant/quickstart.md +20 -0
- package/dist/developer/multi-vendor/installation.md +45 -0
- package/dist/developer/multi-vendor/quickstart.md +17 -0
- package/dist/developer/sdk/admin/quickstart.md +22 -0
- package/dist/developer/sdk/authentication.md +89 -0
- package/dist/developer/sdk/configuration.md +225 -0
- package/dist/developer/sdk/quickstart.md +82 -0
- package/dist/developer/sdk/store/account.md +67 -0
- package/dist/developer/sdk/store/cart-checkout.md +140 -0
- package/dist/developer/sdk/store/markets.md +151 -0
- package/dist/developer/sdk/store/payments.md +96 -0
- package/dist/developer/sdk/store/products.md +149 -0
- package/dist/developer/sdk/store/wishlists.md +52 -0
- package/dist/developer/security/pci_compliance.md +15 -0
- package/dist/developer/security/security_policy.md +68 -0
- package/dist/developer/storefront/blocks.md +285 -0
- package/dist/developer/storefront/custom-css.md +260 -0
- package/dist/developer/storefront/custom-javascript.md +166 -0
- package/dist/developer/storefront/helper-methods.md +1288 -0
- package/dist/developer/storefront/links.md +298 -0
- package/dist/developer/storefront/nextjs/architecture.md +150 -0
- package/dist/developer/storefront/nextjs/customization.md +141 -0
- package/dist/developer/storefront/nextjs/deployment.md +180 -0
- package/dist/developer/storefront/nextjs/quickstart.md +92 -0
- package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
- package/dist/developer/storefront/pages.md +163 -0
- package/dist/developer/storefront/sections.md +569 -0
- package/dist/developer/storefront/storefront.md +56 -0
- package/dist/developer/storefront/themes.md +161 -0
- package/dist/developer/tutorial/admin.md +134 -0
- package/dist/developer/tutorial/extending-models.md +380 -0
- package/dist/developer/tutorial/file-uploads.md +121 -0
- package/dist/developer/tutorial/introduction.md +33 -0
- package/dist/developer/tutorial/model.md +41 -0
- package/dist/developer/tutorial/page-builder.md +487 -0
- package/dist/developer/tutorial/rich-text.md +73 -0
- package/dist/developer/tutorial/seo.md +332 -0
- package/dist/developer/tutorial/storefront.md +352 -0
- package/dist/developer/tutorial/testing.md +558 -0
- package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
- package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
- package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
- package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
- package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
- package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
- package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
- package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
- package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
- package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
- package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
- package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
- package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
- package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
- package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
- package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
- package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
- package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
- package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
- package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
- package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
- package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
- package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
- package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
- package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
- package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
- package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
- package/dist/developer/upgrades/quickstart.md +36 -0
- package/dist/integrations/analytics/google-analytics.md +64 -0
- package/dist/integrations/analytics/google-tag-manager.md +78 -0
- package/dist/integrations/integrations.md +39 -0
- package/dist/integrations/marketing/klaviyo.md +99 -0
- package/dist/integrations/payments/adyen.md +90 -0
- package/dist/integrations/payments/paypal.md +41 -0
- package/dist/integrations/payments/razorpay.md +45 -0
- package/dist/integrations/payments/stripe.md +109 -0
- package/dist/integrations/search/meilisearch.md +236 -0
- package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
- package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
- package/package.json +27 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Dependencies
|
|
3
|
+
section: customization
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
With Dependencies, you can easily replace parts of Spree core with your custom code. You can replace [Services](https://github.com/spree/spree/tree/master/core/app/services/spree), CanCanCan Abilities (used for [Permissions](permissions)), and [API Serializers](https://github.com/spree/spree/tree/master/api/app/serializers/spree/v2) (used for generating JSON API responses).
|
|
9
|
+
|
|
10
|
+
## Application (global) customization
|
|
11
|
+
|
|
12
|
+
This will change every aspect of the application (both APIs, Admin Panel, and Storefront).
|
|
13
|
+
|
|
14
|
+
In your `config/initializers/spree.rb` file, you can set the following:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
Spree.cart_add_item_service = MyAddToCartService
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or using the block syntax:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
Spree.dependencies do |dependencies|
|
|
24
|
+
dependencies.cart_add_item_service = MyAddToCartService
|
|
25
|
+
end
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Now let's create your custom service.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
mkdir -p app/services && touch app/services/my_add_to_cart_service.rb
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
And add the following code to it:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
class MyAddToCartService < Spree::Cart::AddItem
|
|
38
|
+
def call(order:, variant:, quantity: nil, public_metadata: {}, private_metadata: {}, options: {})
|
|
39
|
+
ApplicationRecord.transaction do
|
|
40
|
+
run :add_to_line_item
|
|
41
|
+
run Spree.cart_recalculate_service
|
|
42
|
+
run :update_in_external_system
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def update_in_external_system(new_order_line_item)
|
|
49
|
+
# Your custom logic here
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This code will:
|
|
55
|
+
|
|
56
|
+
1. Inherit from `Spree::Cart::AddItem`
|
|
57
|
+
2. Override the `call` method to add your custom logic
|
|
58
|
+
3. Call `run :add_to_line_item` to add the item to the cart
|
|
59
|
+
4. Call `run Spree.cart_recalculate_service` to recalculate the cart (returns the resolved class)
|
|
60
|
+
5. Call `run :update_in_external_system` to execute your custom logic, eg. updating Order in an external system such as ERP
|
|
61
|
+
|
|
62
|
+
## Using dependencies in your code
|
|
63
|
+
|
|
64
|
+
When you need to use a dependency in your code, you can access it directly via the `Spree` module:
|
|
65
|
+
|
|
66
|
+
```ruby
|
|
67
|
+
# Returns the resolved class (not a string)
|
|
68
|
+
Spree.cart_add_item_service.call(order: order, variant: variant, quantity: 1)
|
|
69
|
+
|
|
70
|
+
# For API dependencies, use the Spree.api accessor
|
|
71
|
+
Spree.api.storefront_cart_serializer.new(order).serializable_hash
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Controller level customization
|
|
75
|
+
|
|
76
|
+
If you need to replace [serializers](https://github.com/jsonapi-serializer/jsonapi-serializer) or Services in a specific API endpoint you can create a [code decorator](/developer/customization/decorators):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mkdir -p app/controllers/spree && touch app/controllers/spree/cart_controller_decorator.rb
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
and add the following code to it:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
module Spree
|
|
86
|
+
module CartControllerDecorator
|
|
87
|
+
def resource_serializer
|
|
88
|
+
MyNewAwesomeCartSerializer
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def add_item_service
|
|
92
|
+
MyNewAwesomeAddItemToCart
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
CartController.prepend(CartControllerDecorator)
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This will change the serializer in this API endpoint to `MyNewAwesomeCartSerializer` and also it will swap the default `add_item_service` to `MyNewAwesomeAddItemToCart`.
|
|
101
|
+
|
|
102
|
+
Different API endpoints can have different dependency injection points. You can review their [source code](https://github.com/spree/spree/tree/master/api/app/controllers/spree/api/v2) to see what you can replace.
|
|
103
|
+
|
|
104
|
+
## API level customization
|
|
105
|
+
|
|
106
|
+
Storefront API and Platform API have separate Dependencies injection points so you can easily customize one without touching the other.
|
|
107
|
+
|
|
108
|
+
In your Spree initializer (`config/initializers/spree.rb`) please add:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
Spree.api.storefront_cart_serializer = MyNewAwesomeCartSerializer
|
|
112
|
+
Spree.api.storefront_cart_add_item_service = MyNewAwesomeAddItemToCart
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
This will swap the default Cart serializer and Add Item to Cart service for your custom ones within all Storefront API endpoints that use those classes.
|
|
116
|
+
|
|
117
|
+
You can mix and match both global and API-level customizations:
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
Spree.cart_add_item_service = MyNewAwesomeAddItemToCart
|
|
121
|
+
Spree.api.storefront_cart_add_item_service = AnotherAddItemToCart
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The second line will have precedence over the first one, and the Storefront API will use `AnotherAddItemToCart` and the rest of the application will use `MyNewAwesomeAddItemToCart`.
|
|
125
|
+
|
|
126
|
+
## Debugging dependencies
|
|
127
|
+
|
|
128
|
+
Spree provides rake tasks to help you debug and inspect dependencies:
|
|
129
|
+
|
|
130
|
+
### List all dependencies
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
bin/rake spree:dependencies:list
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This will output all dependencies with their current values:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
[CORE]
|
|
140
|
+
cart_add_item_service Spree::Cart::AddItem
|
|
141
|
+
cart_create_service Spree::Cart::Create
|
|
142
|
+
cart_recalculate_service Spree::Cart::Recalculate [OVERRIDDEN]
|
|
143
|
+
...
|
|
144
|
+
|
|
145
|
+
[API]
|
|
146
|
+
storefront_cart_serializer Spree::V2::Storefront::CartSerializer
|
|
147
|
+
storefront_cart_add_item_service MyApp::CartAddItem [OVERRIDDEN]
|
|
148
|
+
...
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
You can use `grep` to filter results:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
bin/rake spree:dependencies:list | grep cart
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Show only overridden dependencies
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
bin/rake spree:dependencies:overrides
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This shows only the dependencies that have been customized, along with their original and current values:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
[Core OVERRIDES]
|
|
167
|
+
cart_recalculate_service Spree::Cart::Recalculate -> MyApp::CartRecalculate (config/initializers/spree.rb:15)
|
|
168
|
+
|
|
169
|
+
[API OVERRIDES]
|
|
170
|
+
storefront_cart_add_item_service Spree::Cart::AddItem -> MyApp::CartAddItem (config/initializers/spree.rb:20)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Validate all dependencies
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
bin/rake spree:dependencies:validate
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
This validates that all dependencies can be resolved to valid classes. If any dependency points to a non-existent class, it will report an error:
|
|
180
|
+
|
|
181
|
+
```
|
|
182
|
+
..........F.........
|
|
183
|
+
1 invalid dependencies:
|
|
184
|
+
[Core] cart_add_item_service: uninitialized constant NonExistentClass
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Programmatic introspection
|
|
188
|
+
|
|
189
|
+
You can also inspect dependencies programmatically:
|
|
190
|
+
|
|
191
|
+
```ruby
|
|
192
|
+
# Check all current values
|
|
193
|
+
Spree::Dependencies.current_values
|
|
194
|
+
# => [{name: :cart_add_item_service, current: MyApp::CartAddItem, default: 'Spree::Cart::AddItem', overridden: true}, ...]
|
|
195
|
+
|
|
196
|
+
# Check if a specific dependency is overridden
|
|
197
|
+
Spree::Dependencies.overridden?(:cart_add_item_service)
|
|
198
|
+
# => true
|
|
199
|
+
|
|
200
|
+
# Get override information (where it was set)
|
|
201
|
+
Spree::Dependencies.override_info(:cart_add_item_service)
|
|
202
|
+
# => {value: MyApp::CartAddItem, source: "config/initializers/spree.rb:15", set_at: 2024-01-15 10:30:00}
|
|
203
|
+
|
|
204
|
+
# Validate all dependencies resolve to valid classes
|
|
205
|
+
Spree::Dependencies.validate!
|
|
206
|
+
# => true (or raises Spree::DependencyError)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Backwards compatibility
|
|
210
|
+
|
|
211
|
+
The legacy string-based syntax is still supported for backwards compatibility:
|
|
212
|
+
|
|
213
|
+
```ruby
|
|
214
|
+
# Legacy syntax (still works)
|
|
215
|
+
Spree::Dependencies.cart_add_item_service = 'MyAddToCartService'
|
|
216
|
+
result = Spree::Dependencies.cart_add_item_service.constantize
|
|
217
|
+
|
|
218
|
+
# New syntax (recommended)
|
|
219
|
+
Spree.cart_add_item_service = MyAddToCartService
|
|
220
|
+
result = Spree.cart_add_item_service
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Both syntaxes can coexist, but the new syntax is recommended as it's more concise and provides better error messages at assignment time.
|
|
224
|
+
|
|
225
|
+
## Default values
|
|
226
|
+
|
|
227
|
+
Default values can be easily checked by:
|
|
228
|
+
|
|
229
|
+
1. Using the rake task: `bin/rake spree:dependencies:list`
|
|
230
|
+
2. Looking at the source code:
|
|
231
|
+
* [Application (global) dependencies](https://github.com/spree/spree/blob/main/core/lib/spree/core/dependencies.rb)
|
|
232
|
+
* [API level dependencies](https://github.com/spree/spree/blob/main/api/lib/spree/api/dependencies.rb)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Emails
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
> **NOTE:** Emails are now part of `spree_emails` gem. If you use `spree_starter` you already have it installed.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Spree uses [postmark templates](https://github.com/wildbit/postmark-templates), as a base for all transactional emails.
|
|
10
|
+
|
|
11
|
+
## Email previews
|
|
12
|
+
|
|
13
|
+
Spree offers an emails preview generator for development purposes. To generate them, use the command:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bin/rails g spree:emails:install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
After that, start the rails server locally and go to: `localhost:3000/rails/mailers`
|
|
20
|
+
|
|
21
|
+
(it requires a seeded development database in order to work properly)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Extensions
|
|
3
|
+
description: >-
|
|
4
|
+
Extensions provide additional features and integrations for your Spree
|
|
5
|
+
application. Here's a list of the most popular ones.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
> **TIP:** For officially supported 3rd party integrations, please go to [Integrations](/integrations) page.
|
|
9
|
+
|
|
10
|
+
<details>
|
|
11
|
+
<summary>Customer Service</summary>
|
|
12
|
+
|
|
13
|
+
- [Gladly](https://github.com/upsidelab/spree_gladly) — Allows you to connect your Spree store with [Gladly](https://www.gladly.com/) service. It allows Gladly agents to see basic information about Spree customers and their orders.
|
|
14
|
+
|
|
15
|
+
</details>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Internationalization</summary>
|
|
20
|
+
|
|
21
|
+
- [Spree I18n](https://github.com/spree-contrib/spree_i18n) — Spree I18n is a gem that provides a way to translate Spree applications into multiple languages. It allows you to translate the UI and have different translations for product descriptions, taxons, etc to improve conversions and customer satisfaction.
|
|
22
|
+
- [Flow Commerce](https://github.com/mejuri-inc/flowcommerce_spree) — Integration with Flow Commerce API for cross border selling.
|
|
23
|
+
|
|
24
|
+
</details>
|
|
25
|
+
|
|
26
|
+
<details>
|
|
27
|
+
<summary>Order Management</summary>
|
|
28
|
+
|
|
29
|
+
- [Print Invoice](https://github.com/spree-contrib/spree_print_invoice) — Create a PDF invoice for Spree orders.
|
|
30
|
+
|
|
31
|
+
</details>
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
<details>
|
|
35
|
+
<summary>Marketing</summary>
|
|
36
|
+
|
|
37
|
+
- [MailChimp E-Commerce](https://github.com/spree-contrib/spree_mailchimp_ecommerce) — Full Spree Mailchimp E-Commerce integration.
|
|
38
|
+
|
|
39
|
+
</details>
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
<details>
|
|
43
|
+
<summary>Products</summary>
|
|
44
|
+
|
|
45
|
+
- [Volume Pricing](https://github.com/spree-contrib/spree_volume_pricing) — Spree extension which supports sales volume-based pricing quantity discounts.
|
|
46
|
+
- [Products Q&A](https://github.com/TruemarkDev/spree_products_qa) — Q&A Sections for products. Logged in users can ask a question, and then admins are able to answer it. All answered and accepted questions are displayed on a product page.
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
<details>
|
|
52
|
+
<summary>Search</summary>
|
|
53
|
+
|
|
54
|
+
- [SearchKick](https://github.com/spree-contrib/spree_searchkick) — Adds Elasticsearch integration to Spree, powered by [searchkick](https://github.com/ankane/searchkick) gem enabling full-text searching and advanced product filtering.
|
|
55
|
+
|
|
56
|
+
</details>
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
<details>
|
|
60
|
+
<summary>Shipping</summary>
|
|
61
|
+
|
|
62
|
+
- [EasyPost](https://github.com/ShopFelixGray/spree_easypost) — This is an extension to integrate Easy Post into Spree.
|
|
63
|
+
- [ShipStation](https://github.com/MatthewKennedy/spree_shipstation) — Connect your Spree store with ShipStation, allowing ShipStation to pull shipments from your store, and when a shipment is sent, update the order with a tracking number and mark it as shipped.
|
|
64
|
+
|
|
65
|
+
</details>
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
<details>
|
|
69
|
+
<summary>Social</summary>
|
|
70
|
+
|
|
71
|
+
- [Social Login](https://github.com/spree-contrib/spree_social) — Login or signup via Facebook, Twitter, Amazon and other.
|
|
72
|
+
- [Reviews](https://github.com/spree-contrib/spree_reviews) — Straightforward review/rating functionality.
|
|
73
|
+
|
|
74
|
+
</details>
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
<details>
|
|
78
|
+
<summary>Tax Calculation</summary>
|
|
79
|
+
|
|
80
|
+
- [Avatax](https://github.com/spree-contrib/spree_avatax_official) — The new officially certified Spree Avatax Avalara extension.
|
|
81
|
+
- [TaxJar](https://github.com/spree-contrib/spree_taxjar) — Spree Taxjar is a US sales tax extension for Spree using the Taxjar service.
|
|
82
|
+
|
|
83
|
+
</details>
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
<details>
|
|
87
|
+
<summary>Upselling</summary>
|
|
88
|
+
|
|
89
|
+
- [Product Assembly](https://github.com/spree-contrib/spree-product-assembly) — Adds the ability to make product bundles.
|
|
90
|
+
- [Related Products](https://github.com/spree-contrib/spree_related_products) — Possible uses: Accessories, Cross Sells, Up Sells, Compatible Products, Replacement Products, Warranty & Support Products.
|
|
91
|
+
|
|
92
|
+
</details>
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Metadata
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Metadata provides simple, unstructured key-value storage on Spree resources — similar to [Stripe's metadata](https://docs.stripe.com/api/metadata). It's ideal for storing integration IDs, tracking data, or any arbitrary information that doesn't need validation or admin UI.
|
|
8
|
+
|
|
9
|
+
Metadata is **write-only** in the Store API — you can set it when creating or updating resources, but it is never returned in Store API responses. It is visible in Admin API responses for administrative use.
|
|
10
|
+
|
|
11
|
+
> **INFO:** For structured, type-safe custom attributes with admin UI support, use [Metafields](/developer/core-concepts/metafields) instead.
|
|
12
|
+
|
|
13
|
+
## Store API
|
|
14
|
+
|
|
15
|
+
### Cart creation
|
|
16
|
+
|
|
17
|
+
Set metadata when creating a new cart:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
POST /api/v3/store/carts
|
|
21
|
+
Content-Type: application/json
|
|
22
|
+
|
|
23
|
+
{
|
|
24
|
+
"metadata": {
|
|
25
|
+
"source": "mobile_app",
|
|
26
|
+
"campaign": "summer_sale"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
// @spree/sdk
|
|
33
|
+
const cart = await client.carts.create({
|
|
34
|
+
metadata: { source: 'mobile_app', campaign: 'summer_sale' }
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
// @spree/next
|
|
38
|
+
const cart = await getOrCreateCart({ source: 'mobile_app' })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Adding items
|
|
42
|
+
|
|
43
|
+
Set metadata when adding items to the cart:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
POST /api/v3/store/carts/:cart_id/items
|
|
47
|
+
Content-Type: application/json
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
"variant_id": "variant_k5nR8xLq",
|
|
51
|
+
"quantity": 1,
|
|
52
|
+
"metadata": {
|
|
53
|
+
"gift_note": "Happy Birthday!",
|
|
54
|
+
"engraving": "J.D."
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const order = await client.carts.items.create(cartId, {
|
|
61
|
+
variant_id: 'variant_k5nR8xLq',
|
|
62
|
+
quantity: 1,
|
|
63
|
+
metadata: { gift_note: 'Happy Birthday!' },
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Updating items
|
|
68
|
+
|
|
69
|
+
Metadata is **merged** with existing values on update. Set a key to `null` to remove it.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
PATCH /api/v3/store/carts/:cart_id/items/:id
|
|
73
|
+
Content-Type: application/json
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
"metadata": {
|
|
77
|
+
"engraving": "A.B.",
|
|
78
|
+
"gift_note": null
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
You can update metadata without changing quantity, or update both at once:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Metadata only
|
|
87
|
+
await client.carts.items.update(cartId, lineItemId, {
|
|
88
|
+
metadata: { engraving: 'A.B.' },
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
// Both quantity and metadata
|
|
92
|
+
await client.carts.items.update(cartId, lineItemId, {
|
|
93
|
+
quantity: 3,
|
|
94
|
+
metadata: { gift_note: 'Happy Birthday!' },
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Updating carts
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
PATCH /api/v3/store/carts/:id
|
|
102
|
+
Content-Type: application/json
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
"metadata": {
|
|
106
|
+
"utm_source": "google",
|
|
107
|
+
"utm_campaign": "summer_sale"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
await client.carts.update(cartId, {
|
|
114
|
+
metadata: { utm_source: 'google' },
|
|
115
|
+
}, { spreeToken })
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Admin API
|
|
119
|
+
|
|
120
|
+
Metadata is **readable** in Admin API responses on orders and line items:
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"id": "or_m3Rp9wXz",
|
|
125
|
+
"number": "R123456",
|
|
126
|
+
"metadata": {
|
|
127
|
+
"source": "mobile_app",
|
|
128
|
+
"utm_campaign": "summer_sale"
|
|
129
|
+
},
|
|
130
|
+
"items": [
|
|
131
|
+
{
|
|
132
|
+
"id": "li_x8Kp2qWz",
|
|
133
|
+
"metadata": {
|
|
134
|
+
"gift_note": "Happy Birthday!"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
When there is no metadata, the field is `null`.
|
|
142
|
+
|
|
143
|
+
## Ruby / Backend
|
|
144
|
+
|
|
145
|
+
### Reading and writing
|
|
146
|
+
|
|
147
|
+
Every model that includes `Spree::Metadata` has a `metadata` accessor (alias for `private_metadata`):
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
order = Spree::Order.find_by!(number: 'R123456')
|
|
151
|
+
|
|
152
|
+
# Write
|
|
153
|
+
order.metadata = { 'source' => 'mobile_app' }
|
|
154
|
+
order.save!
|
|
155
|
+
|
|
156
|
+
# Read
|
|
157
|
+
order.metadata['source'] # => "mobile_app"
|
|
158
|
+
|
|
159
|
+
# Merge
|
|
160
|
+
order.metadata = order.metadata.merge('campaign' => 'summer')
|
|
161
|
+
order.save!
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Querying
|
|
165
|
+
|
|
166
|
+
```ruby
|
|
167
|
+
# Find orders with specific metadata value (PostgreSQL)
|
|
168
|
+
Spree::Order.where("private_metadata->>'source' = ?", "mobile_app")
|
|
169
|
+
|
|
170
|
+
# Check for key existence
|
|
171
|
+
Spree::Order.where("private_metadata ? 'source'")
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Merge semantics
|
|
175
|
+
|
|
176
|
+
Metadata updates use **merge semantics** — existing keys are preserved, new keys are added, and keys set to `null` are removed. This matches [Stripe's behavior](https://docs.stripe.com/api/metadata).
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
# Initial metadata
|
|
180
|
+
{ "source": "mobile_app", "campaign": "summer" }
|
|
181
|
+
|
|
182
|
+
# Update with
|
|
183
|
+
{ "campaign": "winter", "new_key": "value" }
|
|
184
|
+
|
|
185
|
+
# Result
|
|
186
|
+
{ "source": "mobile_app", "campaign": "winter", "new_key": "value" }
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Metadata vs Metafields
|
|
190
|
+
|
|
191
|
+
| | Metadata | [Metafields](/developer/core-concepts/metafields) |
|
|
192
|
+
|---|---|---|
|
|
193
|
+
| **Use case** | Integration data, tracking, simple key-value | Structured custom attributes with admin UI |
|
|
194
|
+
| **Validation** | None | Type-specific (text, number, boolean, JSON) |
|
|
195
|
+
| **Visibility** | Write-only in Store API, readable in Admin API | Configurable (front-end, back-end, both) |
|
|
196
|
+
| **Admin UI** | Viewable in JSON preview | Full admin management |
|
|
197
|
+
| **Schema** | Schemaless JSON | Defined via MetafieldDefinitions |
|
|
198
|
+
| **API pattern** | Stripe-style flat key-value | Shopify-style typed resources |
|
|
199
|
+
|
|
200
|
+
### When to use metadata
|
|
201
|
+
|
|
202
|
+
- Storing external system IDs (e.g., Stripe payment intent ID, ERP order ID)
|
|
203
|
+
- Tracking attribution data (UTM parameters, referral source)
|
|
204
|
+
- Passing context from the storefront that doesn't need validation
|
|
205
|
+
- Any write-and-forget data that only needs to be read by backend systems
|
|
206
|
+
|
|
207
|
+
### When to use metafields
|
|
208
|
+
|
|
209
|
+
- Custom product specifications shown to customers
|
|
210
|
+
- Admin-managed fields with validation
|
|
211
|
+
- Data that needs to appear in the admin UI
|
|
212
|
+
- Querying/filtering by custom attributes
|
|
213
|
+
|
|
214
|
+
## Supported resources
|
|
215
|
+
|
|
216
|
+
All models that include the `Spree::Metadata` concern support metadata. This includes all core models: Orders, Line Items, Products, Variants, Taxons, Payments, Shipments, and more.
|
|
217
|
+
|
|
218
|
+
The Store API currently supports writing metadata on:
|
|
219
|
+
|
|
220
|
+
- **Carts** — on creation and update (`POST /api/v3/store/carts`, `PATCH /api/v3/store/carts/:id`)
|
|
221
|
+
- **Items** — on create and update (`POST/PATCH /api/v3/store/carts/:id/items`)
|
|
222
|
+
|
|
223
|
+
## Migration from public_metadata
|
|
224
|
+
|
|
225
|
+
The `public_metadata` column is deprecated. Metadata is no longer returned in Store API responses. If you were using `public_metadata` for data that needs to be visible to customers, migrate to [Metafields](/developer/core-concepts/metafields) with `display_on: 'both'`.
|
|
226
|
+
|
|
227
|
+
```ruby
|
|
228
|
+
# Before (deprecated)
|
|
229
|
+
order.public_metadata = { 'gift_message' => 'Happy Birthday!' }
|
|
230
|
+
|
|
231
|
+
# After — use metadata for write-only storage
|
|
232
|
+
order.metadata = { 'gift_message' => 'Happy Birthday!' }
|
|
233
|
+
|
|
234
|
+
# After — use metafields for customer-visible structured data
|
|
235
|
+
order.set_metafield('custom.gift_message', 'Happy Birthday!')
|
|
236
|
+
```
|