📢 Use this project, contribute to it or open issues to help evolve it using Store Discussion.
VTEX Search Result app is responsible for handling the result fetched by the VTEX Search API and displaying it to users.
The app therefore exports all store blocks expected in a search results page, such as the filters and the product gallery.
In your theme's manifest.json
, add the Search Result app as a dependency:
"dependencies": {
"vtex.search-result": "3.x"
}
Now, you are able to use all the blocks exported by the search-result
app. Check out the full list below:
ℹ️ The Search Result app data may be displayed on search pages (store.search
) or any other desired page. When added to the search page, the block that is used must be the search-result-layout
, since it fetches data provided by the template's current search context. If you want to add the app to another page, the block that must be used is the search-result-layout.customQuery
.
According to the desired store page, add the search-result-layout
block or the search-result-layout.customQuery
to the correct template blocks list. For example:
"store.search": {
"blocks": ["search-result-layout"]
}
or
"store.home": {
"blocks": [
"carousel#home",
"shelf#home",
+ "search-result-layout.customQuery#home"
]
}
Now, before declaring all desired blocks for your search result layout, your first need to define how you want the search results to be fetched.
According to your store's scenario, define how the search query data should be fetched using props.
If you are using a search-result-layout
, the blocks will define the data that is fetched from the context
. If what you are using is a search-result-layout.customQuery
, the props should be sent through the querySchema
to configure the custom query.
For example:
{
"store.search": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
}
}
or
{
"store.home": {
"blocks": [
"carousel#home",
"shelf#home",
"search-result-layout.customQuery#home"
]
},
"search-result-layout.customQuery#home": {
"props": {
"querySchema": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
}
}
{
"store.search": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
},
"store.search#category": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
},
"store.search#brand": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
},
"store.search#department": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
},
"store.search#subcategory": {
"blocks": ["search-result-layout"],
"props": {
"context": {
"skusFilter": "FIRST_AVAILABLE",
"simulationBehavior": "skip"
}
}
}
}
Below you may find all available props to configure your search data (be it by using a context or a custom query through the querySchema
block):
Prop name | Type | Description | Default value |
---|---|---|---|
queryField |
string |
Blue . Caution: this prop only works if the mapField prop is declared as well. |
undefined |
mapField |
string |
map parameter to define which results should be fetched in the custom query. For example: specificationFilter_100 . Caution: this prop only works if the queryField prop is declared as well. |
undefined |
maxItemsPerPage |
number |
Maximum number of items per search page. The maximum value of this prop is 50 , if a larger number is passed, the query will fail. |
10 |
orderByField |
enum |
Decides which order products must follow when displayed. The possible values are named after the order type: OrderByTopSaleDESC , OrderByReleaseDateDESC , OrderByBestDiscountDESC , OrderByPriceDESC , OrderByPriceASC , OrderByNameASC , OrderByNameDESC or OrderByScoreDESC (relevance score). ASC and DESC stand for ascending order and descending order, respectively. |
OrderByScoreDESC |
hideUnavailableItems |
boolean |
Whether the search result should display unavailable items (true ) or not (false ). |
false |
facetsBehavior |
string |
Defines the behavior filters will have. When set to dynamic , it restricts the results according to the filters that user have already selected. If set to Static , all filters will continue to be displayed to the user, even is no results exist. |
Static |
skusFilter |
enum |
Controls SKUs returned for each product in the query. The less SKUs needed to be returned, the more performant your shelf query will be. Available value options: FIRST_AVAILABLE (returns only the first available SKU), ALL_AVAILABLE (only returns available SKUs) and ALL (returns all product's SKUs). |
ALL_AVAILABLE |
simulationBehavior |
enum |
Defines whether the search data will be up-to-date (default ) or fetched using the Cache (skip ). The last option should be used only if you prefer faster queries over no having the most up-to-date prices or inventory. |
default |
installmentCriteria |
enum |
Controls what price should be shown when there are different installments options for it. Possible values are: MAX_WITHOUT_INTEREST (displayes the maximum installment option with no interest attached) or MAX_WITH_INTEREST (displayes the maximum installment option whether it has interest attached or not). |
"MAX_WITHOUT_INTEREST" |
Now it is time to structure the search-result-layout
block (or the search-result-layout.customQuery
). They both necessarily require a child: the search-result-layout.desktop
. But you can also provide others, such as the search-result-layout.mobile
and the search-not-found-layout
.
Since these are layout blocks, you can use Flex Layout blocks to build your search results page.
Structure the search-result-layout
or the search-result-layout.customQuery
, according to your store's scenario, by declaring their children and then configuring them using Flex Layout blocks and their props. For example:
{
"search-result-layout": {
"blocks": [
"search-result-layout.desktop",
"search-result-layout.mobile",
"search-not-found-layout"
]
},
"search-result-layout.desktop": {
"children": [
"flex-layout.row#searchbread",
"flex-layout.row#searchtitle",
"flex-layout.row#result"
],
"props": {
"preventRouteChange": true
}
}
}
Available props for search-result-layout.desktop
, search-result-layout.mobile
and search-not-found-layout
:
Prop name | Type | Description | Default value |
---|---|---|---|
hiddenFacets |
Object |
Indicates which filters should be hidden. Possible props and their respective values can be found below. | undefined . |
showFacetQuantity |
boolean |
Whether the result amount in each filter should appear besides its name on the filter-navigator.v3 block as (true ) or (false ) |
false |
blockClass |
string |
Unique block ID to be used in CSS customization | undefined |
trackingId |
string |
ID to be used in Google Analytics to track store metrics based on the Search Result block. | Search result |
mobileLayout |
Object |
Controls how the search results page will be displayed to users when using the mobile layout. Possible props and their respective values can be found below. | undefined |
thresholdForFacetSearch |
number |
Minimum number of facets that must be displayed on the interface for a search bar to be displayed. If you declare 0 , the search bar will always be displayed. |
undefined |
mobileLayout
Object:
Prop name | Type | Description | Default value |
---|---|---|---|
mode1 |
Enum |
Defines the default layout for the mobile search results page. Possible values are: normal , small or inline . |
normal |
mode2 |
Enum |
Defines which layout will be set for the mobile search results page when users click on the layout selector button. Possible values also are: normal , small or inline . |
small |
HiddenFacets
Object:
Prop name | Type | Description | Default value |
---|---|---|---|
brands |
boolean |
Whether Brand filters should be hidden (true ) or not (false ). |
false |
categories |
boolean |
Whether Category filters should be hidden (true ) or not (false ). |
false |
priceRange |
boolean |
Whether Price filters should be hidden (true ) or not (false ). |
false |
specificationFilters |
Object |
Indicates which Specification filters should be hidden. | undefined |
SpecificationFilters
Object:
Prop name | Type | Description | Default value |
---|---|---|---|
hideAll |
boolean |
Whether specification filters should be hidden (true ) or not (false ). |
false |
hiddenFilters |
[object] |
Object array of specification filters that should be hidden. | undefined |
HiddenFilters
object
Prop name | Type | Description | Default value |
---|---|---|---|
name |
string |
Name of the specification filter that you want to hide. | undefined |
From Flex Layout, you will build your search results page using the other blocks that were exported by the Search Result app, such as: gallery
, filter-navigator.v3
, etc.
Therefore, don't forget to check out the Flex Layout documentation for more on how to configure your search results page.
Below you can find the existing props for each of the blocks, in addition to the the rules that govern them.
gallery
block
The gallery block does not have its own props, but it has its own inner block structure that must be configured using a product-summary-shelf
.
This means that any gallery
block implementation created must have a product-summary-shelf
that in turn must also have its own inner block structure that can be configured.
Check out the Product Summary documentation.
filter-navigator.v3
block
Prop name | Type | Description | Default value |
---|---|---|---|
layout |
Enum |
Whether the Filter Navigator layout should be responsive (responsive ) or not (desktop ). You may use desktop when the Filter Navigator was configured to be displayed in a drawer. |
responsive |
maxItemsDepartment |
number |
Maximum number of departments to be displayed before the See More button is triggered. | 8 |
maxItemsCategory |
number |
Maximum number of category items to be displayed before the See More button is triggered. | 8 |
initiallyCollapsed |
Boolean |
Makes the search filters start out collapsed (true ) or open (false ). |
false |
filtersTitleHtmlTag |
string |
HTML tag for the filter's title. | h5 |
scrollToTop |
enum |
Scrolls the page to the top (auto or smooth ) or not (none ) when selecting a facet. |
none |
order-by
block
Prop name | Type | Description | Default value |
---|---|---|---|
hiddenOptions |
[string] |
Indicates which sorting options will be hidden. (e.g. ["OrderByNameASC", "OrderByNameDESC"] ) |
undefined |
The sorting options are:
Sort option | Value |
---|---|
Relevance | "OrderByScoreDESC" |
Top Sales Descending | "OrderByTopSaleDESC" |
Release Date Descending | "OrderByReleaseDateDESC" |
Best Discount Descending | "OrderByBestDiscountDESC" |
Price Descending | "OrderByPriceDESC" |
Price Ascending | "OrderByPriceASC" |
Name Ascending | "OrderByNameASC" |
Name Descending | "OrderByNameDESC" |
search-fetch-more
block TheShow More
button is used to load the results of the next search results page. Even when declared, this block is not rendered if there is no next page.
Prop name | Type | Description | Default value |
---|---|---|---|
htmlElementForButton |
enum |
Which HTML element will be displayed for Show more button component. Possible values are: a (displays a <a> element with href and rel attributes) or button (displays a <button> element without href and rel attributes). |
button |
search-fetch-previous
block TheShow Previous
button is used to load the results of the previous search results page. Even when declared, this block is not rendered if there is no previous page.
Prop name | Type | Description | Default value |
---|---|---|---|
htmlElementForButton |
enum |
Which HTML element will be displayed for Show previous button component. Possible values are: a (displays a <a> element with href and rel attributes) or button (displays a <button> element without href and rel attributes). |
button |
search-products-count-per-page
block Shows the product count per search page. Does not need any prop.search-products-progress-bar
block Shows a progress bar of search results. Does not need any prop.sidebar-close-button
block Close button rendered on the top right of the mobile filter sidebar.
Prop name | Type | Description | Default value |
---|---|---|---|
size |
number |
The size of the button icon | 30 |
type |
string |
The type of the button icon | line |
In order to apply CSS customization in this and other blocks, follow the instructions given in the recipe on Using CSS Handles for store customization.
CSS handles |
---|
accordionFilter |
accordionFilterContainer |
accordionFilterContent |
accordionFilterItemActive |
accordionFilterItemBox |
accordionFilterItemHidden |
accordionFilterItemIcon |
accordionFilterItemOptions |
accordionFilterItemTitle |
accordionFilterItem |
accordionFilterOpen |
border |
breadcrumb |
buttonShowMore |
categoriesContainer |
categoryGroup |
categoryParent |
container |
dropdownMobile |
filter |
filterAccordionBreadcrumbs |
filterBreadcrumbsContent |
filterBreadcrumbsText |
filterBreadcrumbsItem |
filterBreadcrumbsItemName |
filterAccordionItemBox--{facetValue} |
filterApplyButtonWrapper |
filterAvailable |
filterButtonsBox |
filterClearButtonWrapper |
filterContainer--{facetType} |
filterContainer--b |
filterContainer--c |
filterContainer--priceRange |
filterContainer--{selectedFilters} |
filterContainer--{title} |
filterContainer |
filterIcon |
filterItem--{facetValue} |
filterItem--selected |
filterItem |
filterMessage |
filterPopup |
filterPopupArrowIcon |
filterPopupButton |
filterPopupContent |
filterPopupContentContainer |
filterPopupContentContainerOpen |
filterPopupFooter |
filterPopupOpen |
filterPopupTitle |
filterSelected |
filtersWrapper |
filtersWrapperMobile |
filterTemplateOverflow |
filterTitle |
footerButton |
galleryItem |
galleryItem--{displayMode} |
galleryTitle |
gallery |
layoutSwitcher |
loadingOverlay |
loadingSpinnerInnerContainer |
loadingSpinnerOuterContainer |
orderByButton |
orderByDropdown |
orderByOptionItem |
orderByOptionItem--selected |
orderByOptionsContainer |
orderByText |
orderBy |
progressBarContainer |
progressBar |
progressBarFiller |
resultGallery |
searchNotFoundInfo |
searchNotFoundOops |
searchNotFoundTerm |
searchNotFoundTextListLine |
searchNotFoundWhatDoIDo |
searchNotFoundWhatToDoDotsContainer |
searchNotFoundWhatToDoDots |
searchNotFound |
searchResultContainer |
selectedFilterItem |
showingProductsContainer |
showingProductsCount |
showingProducts |
switch |
totalProductsMessage |
totalProducts |
Thanks goes out to these wonderful people (emoji key):
grupo-exito-ecommerce 💻 |
Ygor Neves 💻 |
Marcos André Suarez Ewbank 💻 |
Beatriz Miranda 💻 |
felipeireslan 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!