Custom Products extension
The example explains how Custom Products feature is implemented in vue-demo-store
template (already done), but also can be used as a guide how to deal with the process in any project.
Custom Products for Shopware 6 is an extension that is part of the Shopware Rise plan.
Logic: Composable function
See the source code of useProductCustomizedProductConfigurator
composable function.
The composable is a main place to keep the logic related to custom product features:
- adds TypeScript types
- stores the state
- extracts the custom product's specific data
- exposes method for adding to cart
- serializes the state to be in a correct format for the request's payload (adding to cart)
Example of usage:
WARNING
Works only if the useProduct
is fulfilled and the product data is known. Typically on Product Details Page, when the product context is provided.
Visit the [useProduct]/packages/composables.html#useproduct) reference to see more details.
// useProductCustomizedProductConfigurator is autoimported
// in vue-demo-store template as it's located in ~/composables
const {
isActive, // indicates whether product is empowered by Custom Products extension and active
customizedProduct, // returns the custom product's template data
state, // state to be used in option selector / forms
addToCart, // triggers add to cart action (refreshCart() action invoked afterwards)
handleFileUpload, // uploads an image, then gets mediaId from API and assigns it to the state
} = useProductCustomizedProductConfigurator();
Presentation: Vue component
See the source code of the ProductCustomizedProductConfigurator
Vue component.
The component is responsible for:
- Displaying product options in any type: text field, image upload, select, color select, image select (this one has to be fixed in the core to get the URL's of the images)
- Showing corresponding additional price and currency of an option
Implementation
Add the mentioned component in a template. For instance in <ProductStatic/>
for templates that not come from CMS:
<!-- part of templates/vue-demo-store/components/product/ProductStatic.vue -->
<!-- Options -->
<div class="mt-4 lg:mt-0 lg:row-span-3">
<h2 class="sr-only">Product information</h2>
<div class="product-variants mt-10">
<ProductPrice :product="product" />
<ProductUnits :product="product" class="text-sm" />
<ProductVariantConfigurator @change="handleVariantChange" />
<ProductCustomizedProductConfigurator /> <!-- ADDED -->
<ProductAddToCart :product="product" />
</div>
</div>
Overwrite a logic in <ProductAddToCart/>
(or any other responsible for adding a product to cart in your template):
// part of templates/vue-demo-store/components/product/ProductAddToCart.vue;
// the <script setup lang="ts"> section
const {
addToCart: customizedProductAddToCart,
isActive: isCustomizedProductActive,
} = useProductCustomizedProductConfigurator();
const addToCartProxy = async () => {
if (isCustomizedProductActive.value) {
await customizedProductAddToCart();
} else {
await addToCart();
}
...
Used composable function allows to use addToCart()
method and isActive
computed property. Both are described in "Example of usage" chapter above.
There was a condition added to use a different method to add to cart a product if the product is enhanced by Custom Product template (how to set it up):
- if the product has a Custom Product template, then use
customizedProductAddToCart()
method. - otherwise, don't change the adding to cart behavior and use the default one
Known issues
- Missing images for "Image select" option type (reported in the extension repository)
- Missing cover image (aka thumbnail) for Custom Product in the Cart (reported in the extension repository)
- Display selected option for Cart Item (Issue reported)