Skip to main content

Overview

You are reading an outdated document

Get the latest developer guides on Fynd Partners Help

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

<template>
<div :*class*="{
'section-main-container': !settings.props.full_width.value,
'full-width-section': settings.props.full_width.value,
}">

<h1 *class*="section-heading" *v-if*="settings && settings.props.heading.value">
{{ settings.props.heading.value }}
</h1>
<div class="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>