Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
Conditional Layout
View in Portuguese
This content was migrated from the VTEX Learning Center and is no longer being actively maintained. For the most accurate and up-to-date information, please check the official documentation.

Introduction

At times, when developing a store, we need to create conditional layouts that would apply only to a specific context. We have already seen that when using different devices, it is possible to condition layout using Responsive Layout, but what if we wanted, for example, to have a different product page for specific products? This is what the Conditional Layout is for.

Optional setup

To create a conditional product page layout it is necessary, initially, to have a product page. If you have not already defined a product template for your store, copy the one below:


_70
//product.jsonc
_70
{
_70
"store.product": {
_70
"children": [
_70
"flex-layout.row#product-breadcrumb",
_70
"flex-layout.row#product-main"
_70
]
_70
},
_70
"flex-layout.row#product-breadcrumb": {
_70
"props": {
_70
"marginTop": 20
_70
},
_70
"children": ["breadcrumb"]
_70
},
_70
"flex-layout.row#product-main": {
_70
"props": {
_70
"colGap": 9,
_70
"rowGap": 7,
_70
"marginTop": 4,
_70
"marginBottom": 7,
_70
"paddingTop": 7,
_70
"paddingBottom": 7,
_70
"blockClass": "product-main"
_70
},
_70
"children": ["product-images", "flex-layout.col#right-col"]
_70
},
_70
"product-images": {
_70
"props": {
_70
"displayThumbnailsArrows": true,
_70
"thumbnailsOrientation": "vertical"
_70
}
_70
},
_70
"flex-layout.col#right-col": {
_70
"props": {
_70
"preventVerticalStretch": true,
_70
"rowGap": 0
_70
},
_70
"children": [
_70
"product-name",
_70
"product-price#product-details",
_70
"sku-selector",
_70
"flex-layout.row#buy-button",
_70
"shipping-simulator",
_70
"share#default"
_70
]
_70
},
_70
"product-price#product-details": {
_70
"props": {
_70
"showInstallments": true,
_70
"showSavings": true
_70
}
_70
},
_70
"flex-layout.row#buy-button": {
_70
"props": {
_70
"marginTop": 4,
_70
"marginBottom": 7
_70
},
_70
"children": ["buy-button"]
_70
},
_70
"share#default": {
_70
"props": {
_70
"social": {
_70
"Facebook": true,
_70
"WhatsApp": true,
_70
"Twitter": false,
_70
"Pinterest": true
_70
}
_70
}
_70
}
_70
}

By doing this, we will have a product page like the one shown below:

{"base64":"  ","img":{"width":3152,"height":1306,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":553467,"url":"https://user-images.githubusercontent.com/18701182/90407144-84650180-e07c-11ea-9036-838d4d662ba1.png"}}

Activity

  1. We are going to create an exclusive banner for the Refrigerator Retro refrigerator, for this, use as a first child of the store.product a condition-layout.product:

_10
//product.jsonc
_10
{
_10
"store.product": {
_10
"children": [
_10
+ "condition-layout.product"
_10
...
_10
]
_10
}
_10
...
_10
}

  1. Then define the condition-layout.product, with a specific condition for the Retro Mixer:

_10
//product.jsonc
_10
{
_10
...
_10
+ "condition-layout.product": {
_10
+ "children": [
_10
+ "condition.product#retro-mixer"
_10
+ ]
_10
+ }
_10
}

  1. Now, we need to define the condition for the mixer.

Condition.product requires prop conditions to define which conditions should be applied (see documentation), a condition is divided into three parts:

  • subject: is the data that will be used for comparison purposes, in our case we will use productId, in the documentation it is possible to see all the available options;
  • verb: is the comparative method, we will use is to validate if productId is for a specific product, but we could use: is, is-not,contains or does -not-contain;
  • object: is the value we want to compare, in our case, we will use productId 20.

Thus, the object formed is:


_16
//product.jsonc
_16
{
_16
...
_16
+ "condition.product#retro-mixer": {
_16
+ "props": {
_16
+ "conditions": [
_16
+ {
_16
+ "subject": "productId",
_16
+ "verb": "is",
_16
+ "object": "20"
_16
+ }
_16
+ ]
_16
+ },
_16
+ "children": ["image#retro-mixer-banner"]
_16
+ }
_16
}

NOTE: If you are taking the course in your own store, identify the productId of the product you want to customize and enter the value in the object field. You find out the value by refreshing the page, opening your browser's console and typing __RUNTIME __. Route.params.id:

{"base64":"  ","img":{"width":404,"height":74,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":5412,"url":"https://user-images.githubusercontent.com/18701182/90410392-aeb8be00-e080-11ea-8880-f5470c4e5d00.png"}}

  1. Finally, let's define the retro banner:

_12
//product.jsonc
_12
{
_12
...
_12
+ "image#retro-mixer-banner": {
_12
+ "props": {
_12
+ "src": "https://appliancetheme.vtexassets.com/assets/app/src/retroimage___92a8271aac7c51d2059193bdbe019016.jpg",
_12
+ "width": "100%",
_12
+ "height": "200px",
_12
+ "blockClass": "cover"
_12
+ }
_12
+ }
_12
}

Visit the tested product page to see the layout working, if you are using ʻappliancetheme` and the product is a retro mixer, the url will be:

https://{{seuworkspace}}--appliancetheme.myvtex.com/3-colors-retro-stand-mixer/p:

{"base64":"  ","img":{"width":1278,"height":817,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":725502,"url":"https://user-images.githubusercontent.com/43679629/93816475-f6a5a480-fc2d-11ea-80e9-45f4b7907007.png"}}

To ensure that the conditional layout actually works, visit any other product page, and verify that banner is not applied:

{"base64":"  ","img":{"width":1954,"height":952,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":613036,"url":"https://user-images.githubusercontent.com/18701182/90412377-68b12980-e083-11ea-86a8-99495acfd997.png"}}

End

We reached the last step of the course and learned how to create complex layouts by leveraging simpler blocks, we did not explore all possible layouts, but the idea of ​​all of them is very similar, to learn more visit the section of LAYOUT APPS on the Developer Portal.

Answer sheet

See answer sheet for product.jsonc
product.jsonc

_92
{
_92
"store.product": {
_92
"children": [
_92
"condition-layout.product",
_92
"flex-layout.row#product-breadcrumb",
_92
"flex-layout.row#product-main"
_92
]
_92
},
_92
"condition-layout.product": {
_92
"children": ["condition.product#retro-mixer"]
_92
},
_92
"condition.product#retro-mixer": {
_92
"props": {
_92
"conditions": [
_92
{
_92
"subject": "productId",
_92
"verb": "is",
_92
"object": "20"
_92
}
_92
]
_92
},
_92
"children": ["image#retro-mixer-banner"]
_92
},
_92
"image#retro-mixer-banner": {
_92
"props": {
_92
"src": "https://appliancetheme.vtexassets.com/assets/app/src/retroimage___92a8271aac7c51d2059193bdbe019016.jpg",
_92
"width": "100%",
_92
"height": "200px",
_92
"blockClass": "cover"
_92
}
_92
},
_92
"flex-layout.row#product-breadcrumb": {
_92
"props": {
_92
"marginTop": 20
_92
},
_92
"children": ["breadcrumb"]
_92
},
_92
"flex-layout.row#product-main": {
_92
"props": {
_92
"colGap": 9,
_92
"rowGap": 7,
_92
"marginTop": 4,
_92
"marginBottom": 7,
_92
"paddingTop": 7,
_92
"paddingBottom": 7
_92
},
_92
"children": ["product-images", "flex-layout.col#right-col"]
_92
},
_92
"product-images": {
_92
"props": {
_92
"displayThumbnailsArrows": true,
_92
"thumbnailsOrientation": "vertical"
_92
}
_92
},
_92
"flex-layout.col#right-col": {
_92
"props": {
_92
"preventVerticalStretch": true,
_92
"rowGap": 0
_92
},
_92
"children": [
_92
"product-name",
_92
"product-price#product-details",
_92
"sku-selector",
_92
"flex-layout.row#buy-button",
_92
"shipping-simulator",
_92
"share#default"
_92
]
_92
},
_92
"product-price#product-details": {
_92
"props": {
_92
"showInstallments": true,
_92
"showSavings": true
_92
}
_92
},
_92
"flex-layout.row#buy-button": {
_92
"props": {
_92
"marginTop": 4,
_92
"marginBottom": 7
_92
},
_92
"children": ["buy-button"]
_92
},
_92
"share#default": {
_92
"props": {
_92
"social": {
_92
"Facebook": true,
_92
"WhatsApp": true,
_92
"Twitter": false,
_92
"Pinterest": true
_92
}
_92
}
_92
}
_92
}

See answer sheet for vtex.store-components.css
vtex.store-components.css

_10
.imageElement--cover {
_10
object-fit: cover;
_10
}

On this page