Skip to main content

Overview

Deprecation Notice

Vue-based themes will soon be deprecated. Please switch to React-based themes, as all future updates and support will focus exclusively on React.

Sections are reusable UI components that can be customized by merchants. Section files are present inside the sections folder of a theme.

Anatomy of a section

Sections also are Vue components & hence have a template, script & style tag. These are self-explanatory. A section component has access to $apiSDK object that is a handler for the application SDK client. It can use this object to fetch or update data. Each section also has a prop called settings. The prop value for this object is generated by evaluating the settings schema. This schema is defined inside the <settings> tag.

Example

Below is an example section for showing handpicked products

theme/templates/pages/wishlist.vue
<template>
<div :*className*="{
'section-main-container': !settings.props.full_width.value,
'full-width-section': settings.props.full_width.value,
}">

<h1 *className*="section-heading" *v-if*="settings && settings.props.heading.value">
{{ settings.props.heading.value }}
</h1>
<div className="products" v-if="products.length > 0">
<product-card
*v-for*="(product, index) in products"
:*key*="index"
:product="product"
/>
</div>
</div>
</template>

<settings>
{
"name": "featuredProducts",
"label": "Featured Products",
"props": [
{
"type": "text",
"id": "heading",
"default": "Featured Products",
"label": "Section Heading"
},
{
"type": "checkbox",
"id": "full_width",
"default": false,
"label": "Full width",
"info": "Check to allow items to take the entire width of the viewport"
}
],
"blocks": [
{
"type": "product",
"name": "Product",
"props": [
{
"type": "product",
"id": "product",
"label": "Select a Product",
"info": "Product Item to be displayed"
}
]
}
]
}

</settings>


<script>

import productCard from "@/components/product-card.vue";

export default {
props: ["settings", "apiSDK", "serverProps"],
components: {
"product-card": productCard
},
data: function () {
return {
products: this.serverProps || [],
};
},
initializeServerProps({ apiSDK, settings }) {
const products =
settings?.blocks?.map((b) => {
return b?.props?.product?.value;
}) || [];
return Promise.all(
products.map((slug) => {
return apiSDK.catalog.getProductDetailBySlug({
slug,
});
})
)
.then((results) => {
return results;
})
.catch((e) => console.log);
},
mounted() {
if(!this.products) {
this.fetchProducts()
}
},
methods: {
fetchProducts() {
const productSlugs =
this.settings?.blocks?.map((b) => {
return b?.props?.product?.value;
}) || [];
const promiseArr = productSlugs.map(slug => *this*.$apiSDK.catalog.getProductDetailBySlug({
slug
});
Promise.all(promiseArr)
.then((results) => {
this.products = results;
})
.catch((e) => console.log);
}
}
}

</script>

<style lang="less" scoped>
.section-main-container {
width: 80%
}
.full-width-section {
width: 100%
}

.section-heading {
margin: 10px 0
}

.products {
display: flex;
flex-wrap: wrap;
}
</style>

Was this section helpful?