Skip to main content

Overview

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>