@relewise/web-components
v1.35.1
Published
Relewise is a next generation personalization SaaS-platform, which offers functionality within product- and content recommendations and personalized search. Our official Web Components provide simple and easy components for rendering personalized experien
Readme
Relewise UI Component

Installation
Install via NPM or your preferred package manager:
npm install @relewise/web-componentsInitialising
In order to use the web component, you need to configure RelewiseUI.
initializeRelewiseUI(
{
contextSettings: {
getUser: () => {
return UserFactory.anonymous();
},
language: 'da-dk',
currency: 'DKK',
},
datasetId: RELEWISE_DATASET_ID,
apiKey: RELEWISE_API_KEY,
clientOptions: {
serverUrl: RELEWISE_SERVER_URL,
},
});Replace the RELEWISE_DATASET_ID, RELEWISE_API_KEY, RELEWISE_SERVER_URL with your dataset, api-key and server-url found at My.Relewise.
After which you have access to various components configured with the configuration provided.
Configuring render root
Components render in Shadow DOM by default. To opt in to Light DOM rendering for all Relewise web components, set components.domMode during initialization.
initializeRelewiseUI({
...
components: {
domMode: 'light',
styling: 'default',
},
});Use Light DOM when rendered internals, including custom product and content templates, must be available to normal page CSS or global JavaScript DOM queries. Leave the option unset, or set domMode: 'shadow', to keep the default Shadow DOM behavior and component styles.
In Light DOM mode, baseline component styling is enabled by default. Set styling: 'none' to skip injecting Relewise Light DOM styles and style the markup entirely from page CSS. The styling option only affects Light DOM mode; Shadow DOM components keep their scoped styles.
Updating Context Settings
To update Context Settings after initialization simply call updateContextSettings.
updateContextSettings({
language: 'fr-be',
currency: 'EUR',
});Components depending on Context Settings will re-render once settings have been updated.
Configuring Shoppertainment
Register Shoppertainment features with useShoppertainment.
Adaptive Discovery
Configure the Adaptive Discovery feed through the adaptiveDiscovery subsection. The minimum page size and Product/Content composition are intentionally explicit. Omitting configurationKey uses the Dataset's active default feed configuration.
initializeRelewiseUI({
...
}).useShoppertainment({
adaptiveDiscovery: {
minimumPageSize: 20,
configurationKey: 'homepage',
maximumItems: 60,
dwellThresholdMilliseconds: 2_000,
configure(builder) {
builder
.allowProductsCurrentlyInCart()
.addComposition({
options: {
type: 'Product',
count: { lowerBoundInclusive: 1, upperBoundInclusive: 1 },
},
})
.addComposition({
options: {
type: 'Content',
count: { lowerBoundInclusive: 1, upperBoundInclusive: 1 },
},
});
},
},
}).registerAdaptiveDiscoveryTarget('campaign', {
minimumPageSize: 30,
configure(builder) {
// Configure the complete campaign-specific feed.
},
});A matching target replaces the default Adaptive Discovery configuration. An unknown target reports an error and falls back to the default when one is configured. Targets can also be used without a default configuration, which is useful when each rendered component registers a complete, instance-specific feed configuration.
Render the feed with relewise-adaptive-discovery. It preserves the configured composition order and uses the built-in product and content tiles.
When the shopper scrolls within 400px of the bottom of the rendered feed, the component automatically requests and appends the next items from the initialized feed. Set the optional maximumItems to limit the combined number of rendered Products and Content; omit it for a continuous feed.
Clicks on product and content tiles are automatically tracked against the initialized feed.
<relewise-adaptive-discovery
displayed-at-location="Home page"
target="campaign">
</relewise-adaptive-discovery>| Attribute | Default | Description |
| --- | --- | --- |
| displayed-at-location | Relewise Adaptive Discovery | Location included in the initialization request. |
| target | none | Optional target containing a complete Adaptive Discovery configuration. |
The component exposes product-tile and content-tile CSS parts. Its grid uses the same responsive variables as product and content recommendations:
| CSS custom property | Default | Description |
| --- | --- | --- |
| --relewise-recommendation-grid-columns | 4 | Number of columns above the mobile breakpoint. |
| --relewise-recommendation-grid-mobile-columns | 2 | Number of columns at widths up to 768px. |
| --relewise-recommendation-grid-gap | 1em | Gap between feed tiles. |
Named composition templates
Give a composition a name and register a matching compositionTemplates entry to take over rendering for that composition. Compositions without a matching template continue to use the built-in product and content tiles.
initializeRelewiseUI({
...
}).useShoppertainment({
adaptiveDiscovery: {
minimumPageSize: 20,
configure(builder) {
builder.addComposition({
options: {
type: 'Product',
name: 'featured-products',
count: { lowerBoundInclusive: 1, upperBoundInclusive: 4 },
},
});
},
compositionTemplates: {
'featured-products': (composition, { html, helpers }) => html`
<section class="featured-products">
${composition.products?.map(product => html`
<a
${helpers.trackProductVisibility(product)}
href=${product.data?.Url?.value ?? ''}
@click=${() => helpers.trackProductClick(product)}>
${product.displayName}
</a>
`)}
</section>
`,
},
},
});The callback receives the complete FeedCompositionResult, Lit's html function, the standard template helpers, formatPrice, the current user, click-tracking helpers, and visibility-tracking helpers. Use trackProductClick/trackContentClick when custom markup represents a clicked feed item. Attach trackProductVisibility/trackContentVisibility to each custom item element so it participates in dwell tracking.
Adaptive Discovery automatically tracks dwell for built-in tiles. Dwell tracking starts after the shopper first scrolls, includes items that are at least 90% visible, and reports a window when scrolling resumes. Configure the optional dwellThresholdMilliseconds to change the minimum window duration; it defaults to 2,000 milliseconds. Disconnecting the component does not emit a dwell event.
Configuring Relewise Client
You are required to configure the client that you use to call Relewise. Provide the following configuration during initialization.
The main purpose of the client options is to configure which Relewise server to call. These are almost always different between development and production environments.
initializeRelewiseUI(
{
...
clientOptions: {
serverUrl: RELEWISE_SERVER_URL,
},
});Rendering components
Some components can be set with attributes that specify the behavior of the specific component.
To render a specific component you simply use the corresponding html tag.
E.g. the relewise-purchased-with-product takes in an attribute product-id specifying which product the recommendations should be based on.
<relewise-purchased-with-product product-id="PRODUCT_ID"></relewise-purchased-with-product>Replace the PRODUCT_ID with your own product's id.
Recommendations
Call the useRecommendations function to start rendering recommendation components.
useRecommendations();This can also be done fluently when initializing relewise UI.
initializeRelewiseUI().useRecommendations();Attributes and properties that affect recommendation requests are initialization-time inputs. Configure them before the component connects. Components automatically request again when the Relewise context is updated.
Popular Products
This component renders the most popular products.
<relewise-popular-products displayed-at-location="LOCATION"></relewise-popular-products>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The amount of products to render.
since-minutes-ago (Optional, Default 20160 - 14 days):
The time interval, in minutes, that the popularity calculation should be based on.
based-on (Optional, Default MostPurchased):
possible values: MostPurchased, MostViewed
The type of behavioral data that recommendations should be based on.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Slots and parts
Product, content, category, and popular search terms recommendation components support a before-results slot. The slotted content is shown only when recommendations are available. Components without slotted content retain their existing layout. For product, content, and category recommendations, using the slot wraps the results in the recommendation-grid CSS part and a type-specific part (product-recommendation-grid, content-recommendation-grid, or category-recommendation-grid) so the nested grid remains customizable.
<relewise-popular-products displayed-at-location="Front page">
<h2 slot="before-results">Recommended for you</h2>
</relewise-popular-products>relewise-popular-products::part(recommendation-grid) {
grid-template-columns: repeat(3, minmax(0, 1fr));
}Popular Product Categories
This component renders the most popular product categories.
<relewise-popular-product-categories displayed-at-location="LOCATION"></relewise-popular-product-categories>Attributes
displayed-at-location:
Where the recommendations are being shown.
number-of-recommendations (Optional, Default 4):
The number of product category recommendations to render.
since-minutes-ago (Optional, Default 20,160 (14 days)):
The time interval, in minutes, that the popularity calculation should be based on.
target (Optional):
Selects an additional targeted configuration. You can read more here.
Product category recommendations use selectedPropertiesSettings.productCategory, filters.productCategory, and relevanceModifiers.productCategory. The default selected data keys are ImageUrl and Url.
Search-Term-Based Products
This component renders product recommendations based on a search term.
<relewise-search-term-based-products term="SEARCH_TERM" displayed-at-location="LOCATION"></relewise-search-term-based-products>Attributes
displayed-at-location:
Where the recommendations are being shown.
term:
The search term that the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of product recommendations to render.
target (Optional):
Selects an additional targeted configuration. You can read more here.
Products viewed after viewing Product
This component renders products typically viewed after viewing a given product.
<relewise-products-viewed-after-viewing-product product-id="PRODUCT_ID" displayed-at-location="LOCATION"></relewise-products-viewed-after-viewing-product>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information, see our docs.
product-id:
The id of the product the recommendations should be based on.
variant-id (Optional):
The id of the product variant the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of product recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Products viewed after viewing Content
This component renders products typically viewed after viewing a given piece of content.
<relewise-products-viewed-after-viewing-content content-id="CONTENT_ID" displayed-at-location="LOCATION"></relewise-products-viewed-after-viewing-content>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information, see our docs.
content-id:
The id of the content the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of product recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Products purchased with Product
This component renders products typically purchased with a given product.
<relewise-purchased-with-product product-id="PRODUCT_ID" displayed-at-location="LOCATION"></relewise-purchased-with-product>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
product-id:
The id of the product the recommendations should be based on.
variant-id (Optional):
The id of the product variant the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of products recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Products Purchased with Multiple Products
This component renders products purchased with multiple products.
The recommendation requires child elements specifying which products and, optionally, variants to base the recommendation on.
<relewise-purchased-with-multiple-products displayed-at-location="LOCATION">
<product-and-variant-id product-id="PRODUCT_ID"></product-and-variant-id>
<product-and-variant-id product-id="PRODUCT_ID" variant-id="VARIANT_ID"></product-and-variant-id>
</relewise-purchased-with-multiple-products>Attributes product-and-variant-id
product-id:
The id of the product the recommendations should be based on.
variant-id (Optional):
The id of the product variant the recommendations should be based on.
Attributes relewise-purchased-with-multiple-products
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The number of products recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Personal Products
This component renders personal products.
<relewise-personal-products displayed-at-location="LOCATION"></relewise-personal-products>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The amount of products to render.
Recently Viewed Products
This component renders recently viewed products. The component will only render results for users who can be identified through tracking. This requires that the user has been tracked with at least an email, identifier, authenticated ID or temporary ID.
<relewise-recently-viewed-products displayed-at-location="LOCATION"></relewise-recently-viewed-products>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The amount of products to render.
Product Recommendation Batcher
This component batches multiple product recommendations into a single request against Relewise. This increases performance, and ensures that there are no duplicate products in the recommendation sliders
<relewise-product-recommendation-batcher>
<h1>Purchased with</h1>
<relewise-purchased-with-product product-id="PRODUCT_ID" displayed-at-location="LOCATION"></relewise-purchased-with-product>
<h1>Viewed after viewing</h1>
<relewise-products-viewed-after-viewing-product product-id="PRODUCT_ID" displayed-at-location="LOCATION"></relewise-products-viewed-after-viewing-product>
</relewise-product-recommendation-batcher>The standalone product, content, category, and popular-search-term recommendation components emit relewise-ui-components:recommendation-state-changed when their renderable state changes. The event bubbles across shadow boundaries and contains { loading: boolean, hasResults: boolean }. It is primarily used when composing recommendation components into a larger search experience.
Popular Content
This component renders popular content.
<relewise-popular-content displayed-at-location="LOCATION"></relewise-popular-content>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
since-minutes-ago (Optional, Default 20160 - 14 days):
The time interval, in minutes, that the popularity calculation should be based on.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Popular Content Categories
This component renders the most popular content categories.
<relewise-popular-content-categories displayed-at-location="LOCATION"></relewise-popular-content-categories>Attributes
displayed-at-location:
Where the recommendations are being shown.
number-of-recommendations (Optional, Default 4):
The number of content category recommendations to render.
since-minutes-ago (Optional, Default 20,160 (14 days)):
The time interval, in minutes, that the popularity calculation should be based on.
target (Optional):
Selects an additional targeted configuration. You can read more here.
Content category recommendations use selectedPropertiesSettings.contentCategory, filters.contentCategory, and relevanceModifiers.contentCategory. The default selected data keys are ImageUrl and Url.
initializeRelewiseUI({
...
selectedPropertiesSettings: {
productCategory: { displayName: true, dataKeys: ['Url', 'ImageUrl'] },
contentCategory: { displayName: true, dataKeys: ['Url', 'ImageUrl'] },
},
filters: {
productCategory: builder => { /* Add product category filters */ },
contentCategory: builder => { /* Add content category filters */ },
},
relevanceModifiers: {
productCategory: builder => { /* Add product category relevance modifiers */ },
contentCategory: builder => { /* Add content category relevance modifiers */ },
},
}).useRecommendations();Popular Search Terms
This component renders popular search terms as buttons. Selecting a term dispatches a bubbling and composed relewise-ui-components:popular-search-term-selected event with { term } in event.detail.
<relewise-popular-search-terms displayed-at-location="LOCATION"></relewise-popular-search-terms>To show content before a nonempty list of terms, use the before-results slot:
<relewise-popular-search-terms displayed-at-location="LOCATION">
<h2 slot="before-results">Popular searches</h2>
</relewise-popular-search-terms>Attributes and properties
displayed-at-location:
Where the recommendations are being shown.
number-of-recommendations (Optional, Default 4):
The number of search terms to render.
term (Optional):
A search term used to make the recommendations contextual.
target (Optional):
Selects an additional targeted configuration. You can read more here.
The entity types used when recommending search terms can be configured when recommendation components are registered. Allowed values are Product, Variant, ProductCategory, Brand, Content, and ContentCategory.
initializeRelewiseUI({
// Other options...
}).useRecommendations({
popularSearchTerms: {
targetEntityTypes: ['Product', 'ProductCategory', 'Content'],
},
});CSS parts
terms: The list containing all recommended terms.term: A recommended search-term button.
Personal Content
This component renders personal content.
<relewise-personal-content displayed-at-location="LOCATION"></relewise-personal-content>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Content Viewed After Viewing Content
This component renders content typically viewed after viewing a given content page.
<relewise-content-viewed-after-viewing-content content-id="CONTENT_ID" displayed-at-location="LOCATION"></relewise-content-viewed-after-viewing-content>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
content-id:
The id of the content item the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Content Viewed After Viewing Multiple Content
This component renders content typically viewed after viewing multiple content pages.
<relewise-content-viewed-after-viewing-multiple-content displayed-at-location="LOCATION">
<content-id content-id="CONTENT_ID"></content-id>
<content-id content-id="ANOTHER_CONTENT_ID"></content-id>
</relewise-content-viewed-after-viewing-multiple-content>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Child elements
<content-id content-id="CONTENT_ID">:Provide one child per content item that the recommendation should be based on. The
content-idattribute holds the id of the content.
Content Viewed After Viewing Product
This component renders content typically viewed after viewing a given product.
<relewise-content-viewed-after-viewing-product product-id="PRODUCT_ID" displayed-at-location="LOCATION"></relewise-content-viewed-after-viewing-product>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
product-id:
The id of the product the recommendations should be based on.
variant-id (Optional):
The id of the product variant the recommendations should be based on.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Content Viewed After Viewing Multiple Products
This component renders content typically viewed after viewing multiple products.
<relewise-content-viewed-after-viewing-multiple-products displayed-at-location="LOCATION">
<product-and-variant-id product-id="PRODUCT_ID"></product-and-variant-id>
<product-and-variant-id product-id="SECOND_PRODUCT_ID" variant-id="VARIANT_ID"></product-and-variant-id>
</relewise-content-viewed-after-viewing-multiple-products>Attributes
displayed-at-location :
Where the recommendations are being shown.
For more information see our docs.
number-of-recommendations (Optional, Default 4):
The number of content recommendations to render.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Child elements
<product-and-variant-id product-id="PRODUCT_ID" variant-id="VARIANT_ID">:Provide one child per product the recommendation should be based on. The
product-idattribute is required, whilevariant-idis optional.
Targeted Recommendations
You can target specific recommendations to ensure certain filters and/or relevance modifiers are only applied to the target. This can be done by calling registerRecommendationTarget either during initialization or afterwards by calling the function independently.
initializeRelewiseUI(
{
...
targets: {
recommendationTargets(builder) {
builder.add({target: 'target', configuration: {
filters(filterBuilder) {
filterBuilder.addProductCategoryIdFilter('ImmediateParent', ['4774']);
},
relevanceModifiers(builder) {
builder.addBrandIdRelevanceModifier('brand1', 1000);
},
}});
},
},
},
);registerRecommendationTarget('target', {
filters(builder) {
builder.addProductCategoryIdFilter('ImmediateParent', ['4774']);
},
relevanceModifiers(builder) {
builder.addBrandIdRelevanceModifier('brand1', 1000);
},
});To specify which recommendation component the configuration should be applied to, simply add the target attribute to the component.
<relewise-popular-products target="target"></relewise-popular-products>Note: The target must match the target specified when calling registerRecommendationTarget!
Search
Call the useSearch function to start rendering search components.
useSearch();Request timing
Search requests are debounced by 300 milliseconds and begin from the first character by default. Configure either behavior through useSearch:
useSearch({
debounceTimeInMs: 500,
minimumQueryLength: 3,
});minimumQueryLength applies to non-empty terms in both the product search overlay and full-page product search. An empty full-page term continues to load products as before.
To specify which filters should be used when searching, call the useSearch function with a configuration.
Note: These filters will be applied on top of the filters defined when initializing Relewise UI.
useSearch({
filters: {
productSearch: (builder) => {
builder
.addProductCategoryIdFilter('ImmediateParent', ['category'])
.addBrandIdFilter(['brand1', 'brand2'])
.addProductAssortmentFilter(1);
},
}
});Adding filters after initialization
If you need to extend the configured filters after calling initializeRelewiseUI, use addFilters to register new filter callbacks without overwriting the existing ones.
import { addFilters } from '@relewise/web-components';
addFilters({
product(builder) {
builder.addProductCategoryIdFilter('ImmediateParent', ['4774']);
},
});The provided callbacks are composed with the filters defined during initialization as well as any previous addFilters calls, ensuring all filters run for subsequent requests.
Sorting
To configure which sorting options should be available in product search, call useSearch with a sorting builder.
By default, the builder starts with the built-in sorting options already configured. Call clear() if you want to replace them completely.
useSearch({
sorting: sorting => sorting
.clear()
.addRelevance()
.addBrandAscending()
.addPopularityDescending()
.addProductData({
label: 'Rating',
key: 'Rating',
selectionStrategy: 'Product',
order: 'Descending',
mode: 'Numerical',
}),
});You can also extend the default sorting menu without clearing it first.
useSearch({
sorting: sorting => sorting.addProductData({
label: 'Stock',
key: 'Stock',
selectionStrategy: 'Product',
order: 'Ascending',
mode: 'Numerical',
}),
});Localization
To overwrite words and sentences used by the search components, call the useSearch function with the desired localization configuration.
useSearch({
localization: {
searchSuggestions: {
label: 'Search suggestions',
},
facets: {
save: 'Save',
showLess: 'Show Less',
showMore: 'Show More',
filter: 'Filter',
yes: 'Yes',
no: 'No',
},
loadMoreButton: {
loadMore: 'Hent flere!',
loadPrevious: 'Hent tidligere!',
showing: 'Viser',
outOf: 'ud af',
products: 'produkter',
},
universalSearch: {
close: 'Close',
emptyState: 'Start typing to search.',
noEntitiesConfigured: 'No universal-search entities configured.',
noResults: 'No results found.',
noResultsHint: 'Try another search term or check the spelling.',
tabsLabel: 'Search result tabs',
products: {
tab: 'Products',
resultsFor: 'Search results for',
resultsTitle: 'Products',
result: 'Result',
results: 'Results',
noResults: 'No products found.',
noResultsHint: 'Try another search term or check the spelling.',
error: 'Could not load products.',
},
productCategories: {
tab: 'Categories',
resultsFor: 'Search results for',
resultsTitle: 'Categories',
result: 'Result',
results: 'Results',
noResults: 'No product categories found.',
noResultsHint: 'Try another search term or check the spelling.',
error: 'Could not load categories.',
},
content: {
tab: 'Content',
resultsFor: 'Search results for',
resultsTitle: 'Content',
result: 'Result',
results: 'Results',
noResults: 'No content found.',
noResultsHint: 'Try another search term or check the spelling.',
error: 'Could not load content.',
},
},
searchBar: {
placeholder: 'Search',
search: 'Search',
},
searchResults: {
noResults: 'No products found',
showAllResults: 'Show all results',
result: 'Result',
results: 'Results',
},
sortingButton: {
sorting: 'sorting',
sortBy: 'Sort by:',
alphabeticalAscending: 'a - z',
alphabeticalDescending: 'z - a',
brandAscending: 'brand a - z',
brandDescending: 'brand z - a',
popularityAscending: 'least popular',
popularityDescending: 'most popular',
relevance: 'Relevance',
salesPriceAscending: 'low - high',
salesPriceDescending: 'high - low',
},
},
});Universal Search
This component renders a universal-search modal that can be opened by a custom trigger. Products, product categories, and content can be included through useSearch({ universalSearch: { entities } }).
The products tab reuses the existing product search configuration for facets, sorting, filters, relevance modifiers, selected properties, and target overrides. Product categories and content reuse their existing filters, relevance modifiers, selected properties, and generalized facet configuration paths.
When universalSearch is provided without entities, the products tab is included with its defaults. When entities is provided, its keys are the exact result types to include: add an entity key to include its tab and omit the key to exclude it. An empty entity option such as products: {} uses that entity's defaults. An explicitly empty entities: {} configuration renders no result tabs.
useSearch({
facets: {
product(builder) {
builder.addFacet(f => f.addBrandFacet(), { heading: 'Brand' });
},
productCategory(builder) {
builder.addFacet(f => f.addProductCategoryDataStringValueFacet('Gender'), { heading: 'Gender' });
},
content(builder) {
builder.addFacet(f => f.addContentDataStringValueFacet('ContentType'), { heading: 'Content type' });
},
},
sorting: sorting => sorting
.clear()
.addRelevance()
.addSalesPriceAscending(),
universalSearch: {
entities: {
products: {},
productCategories: {
pageSize: 12,
},
content: {},
},
suggestions: {
popularSearchTerms: {
take: 5,
targetEntityTypes: ['Product', 'ProductCategory', 'Content'],
},
searchTermPredictions: {
take: 5,
targetEntityTypes: ['Product'],
},
},
behavior: {
zeroResultTabs: 'show',
activateFirstTabWithResults: true,
},
recommendations: {
initial: [
{ type: 'PopularProducts', title: 'Popular products', take: 4 },
{ type: 'PersonalProducts', title: 'Recommended products', take: 4 },
{ type: 'RecentlyViewedProducts', title: 'Recently viewed', take: 4 },
{ type: 'PopularProductCategories', title: 'Popular categories', take: 4 },
],
noResults: {
whenAllTabsAreHidden: [
// Use this when the dataset has enough search-term recommendation data:
// { type: 'SearchTermBasedProduct', title: 'You might like', take: 4 },
{ type: 'PopularProducts', title: 'Popular products', take: 4 },
],
products: [
{ type: 'PopularProducts', title: 'Popular products', take: 4 },
],
productCategories: [
{ type: 'PopularProductCategories', title: 'Popular categories', take: 4 },
],
content: [
{ type: 'PopularContents', title: 'Popular content', take: 4 },
],
},
},
},
});<button onclick="document.querySelector('relewise-universal-search').open()">
Search
</button>
<relewise-universal-search displayed-at-location="LOCATION"></relewise-universal-search>When the component is connected with an existing rw-term URL parameter, it restores that term and automatically opens Universal Search. The close button, Escape key, backdrop, and close() method clear its term, facet, sorting, and pagination URL state so the next open starts clean.
Universal Search bases its internal responsive layout on the available dialog width. Dialogs below 64rem (typically 1024px) use a facet drawer, while dialogs at least 64rem wide use the desktop columns and facet rail. Product results and product recommendations default to three columns below 64rem, two columns at up to 48rem, and one column at up to 28rem; explicit column variables continue to override these defaults. At up to 48rem, the search input and close button remain on one line, filter and sorting controls share a row, and search suggestions join the normal document flow. This also makes a consumer-configured narrow dialog behave compactly on a wide viewport.
The default appearance is intentionally neutral. Use the documented CSS custom properties for sizing and columns, and CSS parts for detailed presentation, without changing the component's search behavior.
When multiple entities are configured, they are searched together in one batched request when the search term changes. A single configured entity uses its direct search endpoint. Omitted entities are not rendered and are not requested. Facet, sorting, and load-more changes only search the active tab.
Search suggestions are opt-in. Configure popularSearchTerms to show popular terms while the focused input is empty, and configure searchTermPredictions to show predictions while it contains text. Both sections default to five terms when take is omitted. Their targetEntityTypes can be configured independently; when omitted, each defaults to the enabled Universal Search entities. This allows an entity to remain searchable without using it as a prediction source. Predictions that exactly match the current input are omitted.
Search redirects returned by the enabled products search follow the product-search overlay behavior. Redirects with a valid destination and a Title data entry appear before search-term predictions as clickable suggestions with an outbound arrow icon, including when term suggestions are not configured. Selecting one navigates directly to its destination. Pressing Enter without selecting a suggestion navigates to the first valid redirect, including an untitled redirect. Redirects are unavailable when the products entity is omitted because the other search response types do not include them.
The suggestions panel supports pointer selection and Arrow Up, Arrow Down, Enter, and Escape. It closes on selection, Enter, Escape, outside interaction, or input blur. Popular terms may be empty when the dataset does not have enough engaged search history; an empty suggestions panel is not rendered.
Universal Search renders its input and suggestions with the shared relewise-search-combobox. The existing relewise-search-bar and product-search overlay remain unchanged, while other search experiences can adopt the combobox later. A populated combobox renders a keyboard-accessible Clear Search button, restores focus to the input after clearing, and resolves its accessible label from localization.searchBar.clear with Clear search as the fallback. Both relewise-search-combobox and relewise-universal-search expose the CSS parts search-input, search-icon, clear-search, search-suggestions, popular-search-terms, predictions, suggestions-list, suggestion, and suggestion-icon.
The combobox owns its input, suggestions popup, focus, outside-interaction dismissal, keyboard, localization, and accessibility behavior. Its redirects property accepts RedirectResult[] for titled redirect suggestions and emits relewise-search-combobox-redirect-selected when one is selected. It loads popular search terms itself and caches a completed response, including an empty response, while it remains connected. Search-term predictions participate in the parent search experience's batch instead of starting a competing request: the parent calls prepareBatchSearch(settings), includes the returned request in its batch, and then calls applyResponse(response) or setError(). Universal Search handles this integration automatically. A future Product Search integration can use the same contract without changing the existing relewise-search-bar or product-search overlay.
The public combobox updates its own term and emits these bubbling, composed events:
| Event | Detail | When |
| --- | --- | --- |
| relewise-search-combobox-term-changed | { term: string } | The input value changes or a suggestion is selected. |
| relewise-search-combobox-search-submitted | { term: string } | Enter is pressed or a suggestion is selected. |
| relewise-search-combobox-redirect-selected | { destination: string } | A redirect suggestion is selected. |
| relewise-search-combobox-escape-requested | None | Escape is pressed when there is no open suggestions list to dismiss. |
const predictionSearch = searchCombobox.prepareBatchSearch(settings);
if (predictionSearch) {
requestBuilder.addRequest(predictionSearch.request);
try {
const response = await searcher.batch(requestBuilder.build());
predictionSearch.applyResponse(response);
} catch {
predictionSearch.setError();
}
}The suggestions popup uses the shared rounded-corner default, clips hover backgrounds to those corners, and has no empty padding above or below the suggestion rows. Its default shadow and hover color match the product-search overlay.
Universal Search can compose the standalone recommendation components into the termless initial state, the whenAllTabsAreHidden no-result state, and each entity tab's no-result state. Every state accepts an ordered UniversalSearchRecommendationBlock[]; omit a state or block to disable it. The composition component is internal to Universal Search and is not registered or exported as a standalone public component.
The top-level localization.universalSearch.noResults and noResultsHint values customize the no-result state shown when all zero-result tabs are hidden. The corresponding values under products, productCategories, and content customize the state shown inside a visible zero-result tab. Set a noResultsHint to an empty string to omit the secondary guidance.
Each block accepts type, optional title, and optional take; take defaults to five so a block fills the default desktop row. Set title to an empty string to omit the heading.
export interface UniversalSearchRecommendationBlock {
title?: string;
type:
| 'PopularProducts'
| 'PersonalProducts'
| 'RecentlyViewedProducts'
| 'PopularProductCategories'
| 'PopularContents'
| 'PersonalContent'
| 'PopularContentCategories'
| 'PopularSearchTerms'
| 'SearchTermBasedProduct';
take?: number;
}The number requested is configured with each block's take. Recommendation grids composed inside Universal Search use the same entity-specific desktop and compact column variables as its result grids. Standalone recommendation grids continue to default to four desktop columns and two mobile columns.
recommendations: {
initial: [
{ type: 'PopularProducts', title: 'Popular products', take: 10 },
{ type: 'PersonalProducts', title: 'Recommended products', take: 10 },
{ type: 'PopularProductCategories', title: 'Popular categories', take: 5 },
{ type: 'PopularContents', title: 'Popular content', take: 10 },
{ type: 'PersonalContent', title: 'Recommended content', take: 10 },
],
noResults: {
whenAllTabsAreHidden: [
{ type: 'PopularProducts', title: 'You might also like', take: 10 },
],
products: [
{ type: 'SearchTermBasedProduct', title: 'Recommended products', take: 10 },
{ type: 'PopularProducts', title: 'Popular products', take: 10 },
],
productCategories: [
{ type: 'PopularProductCategories', title: 'Popular categories', take: 5 },
],
content: [
{ type: 'PopularContents', title: 'Popular content', take: 10 },
],
},
}SearchTermBasedProduct may return no recommendations on a new dataset without enough search behavior. Popular entity recommendations are therefore safer defaults for no-result recovery. PopularSearchTerms uses the centralized useRecommendations({ popularSearchTerms: { targetEntityTypes } }) setting. Universal Search normally hides facets, their reserved column, and the redundant entity heading and 0 Results count for a tab with zero results. When the URL contains both a search term and selected facet state for that entity, it keeps that tab active and visible with the facets from the current response so the filters can be reverted. The tab-specific zero-result message remains visible above any recovery recommendations so the recommendations are not mistaken for search hits. An unselected checklist facet with one option is hidden only when that option covers every current hit; selected options remain visible so they can be removed. Checklist facet titles show the number of selected values, including selections hidden below Show More.
Number-range facets show the current available bounds as their default values without native min or max input constraints. Apply or Enter commits an edited range only when it remains within the available bounds and the lower value does not exceed the upper value; otherwise the inputs return to their last applied values. Bounds restored from a shared URL remain visible as already-applied values even when they exceed the current available range.
Set behavior.zeroResultTabs to show (the default) to keep zero-result tabs and render their configured recovery blocks. Set it to hide to use the whenAllTabsAreHidden recovery blocks when every enabled tab has zero results. A tab with selected facet state remains visible as an exception so those filters can be reverted. behavior.activateFirstTabWithResults defaults to true; after each term search, it selects the first tab with results when the active tab has zero results and no selected facets. Set it to false to retain any active zero-result tab when zero-result tabs are shown.
All configured initial blocks are mounted together. When an active recommendation state contains more than one recommendation block for the same entity type, Universal Search uses that entity type's batch endpoint and requires distinct entities across its responses. Products, content, product categories, and content categories are batched independently and are never combined into one mixed batch. A single recommendation block of an entity type keeps its standalone request lifecycle. The same rule applies to an active entity tab's zero-result recommendations.
No-result recommendations are lazy. Universal Search mounts only the active zero-result tab's configured recommendations and mounts another tab's recommendations when that tab is selected. Leaving a tab disconnects its recommendation children, so returning to it starts their normal standalone lifecycle again. Recommendation results retain the configured block order.
Universal Search forwards the recommendation composition CSS parts, including recommendation-loading, recommendation-blocks, recommendation-block, recommendation-title, the entity grid parts, the actual recommendation tile parts, term parts, and type-specific block parts such as popular-products and search-term-based-products.
Both the tabbed and tabless no-result states expose the CSS parts zero-results, zero-results-icon, zero-results-title, and zero-results-hint through relewise-universal-search.
Responsive layout parts
| Area | Parts |
| --- | --- |
| Shell | backdrop, dialog, header, search-bar, close-button, body |
| Navigation | results-summary, tabs, tab, tab-count |
| Facets | facets, facet-trigger, facet-panel, facet-drawer, facet-drawer-backdrop, facet-drawer-header, facet-drawer-close, facet-container, facet-title, facet-selected-count, facet-input, facet-label, facet-value, facet-hits |
| Results | results-layout, results, results-header, results-title, results-count, product-grid, category-grid, content-grid, product-tile, category-tile, content-tile |
| Sorting | sorting, sorting-container, sorting-select, sorting-label |
| States and pagination | empty-state, error-state, loading-state, zero-results, zero-results-icon, zero-results-title, zero-results-hint, load-previous, load-more |
Recommendation parts are listed above. Parts originating inside the combobox, facet, sorting, tile, load-more, and recommendation components are forwarded through relewise-universal-search.
The current tabs use load-more behavior. When a product result count is restored from rw-product-take, Universal Search requests only the last configured page and exposes load-previous when earlier products can be loaded. Additional pagination modes are not part of the initial universal-search implementation.
Attributes
displayed-at-location :
Where the universal-search component is being shown.
target (Optional):
Applies matching targeted product-search facets and sorting to the products tab.
open (Optional, true/false):
Opens the modal. The component can also be controlled through the
open()andclose()methods.
Product Search Overlay
This component renders a search bar that will search for products in Relewise and show results in an overlay.
Search Redirects is supported in the product search overlay, by default we redirect the user on "Enter", when a Redirect matches the search term. If you want the Redirects listed as suggestions, you can add a "Title" data entry on the Redirect to get them shown. Redirect destinations can be absolute URLs or relative URLs resolved against the current page.
<relewise-product-search-overlay displayed-at-location="LOCATION"></relewise-product-search-overlay>The component renders products but does not use the default product template.
To overwrite the template used in this specific component, call the useSearch function with the templates option.
useSearch({
filters: { ... },
templates: {
searchOverlayProductResult: (product, { html, helpers }) => {
return html`<!-- Write your template here -->`;
},
}
});Attributes
displayed-at-location :
Where the search bar is being shown.
For more information see our docs.
number-of-products (Optional, Default 5):
The number of products shown in the results overlay.
number-of-search-term-predictions (Optional, Default 3):
The number of search term predictions shown in the results overlay.
search-page-url (Optional):
The url of your search page. When provided, an option to go to the search page will be present, when results are found.
navigate-on-suggestion (Optional, true/false, Default false):
When true, clicking a search term suggestion immediately redirects to the configured search page using that term. Requires search-page-url to be set; otherwise the overlay falls back to autofilling the input and logs a warning.
autofocus (Optional, true/false):
Toggle whether or not the input field should be focused on load.
Product Search
This component renders a search component that searches for products in Relewise and shows results, faceting and sorting options.
<relewise-product-search displayed-at-location="LOCATION"></relewise-product-search>Attributes
displayed-at-location :
Where the search component is being shown.
For more information see our docs.
number-of-products (Optional, Default 16):
The number of products to search for initially.
target (Optional):
The target for the additional specific configuration added. You can read more here.
Styling the component
Several parts of the search-overlay are exposed via parts, that allow you some easy hooks to customize how the component looks.
relewise-product-search-overlay::part(searchbar) {
...
}
relewise-product-search-overlay::part(searchbar-input) {
...
}
relewise-product-search-overlay::part(searchbar-icon) {
...
}
relewise-product-search-overlay::part(overlay) {
...
}
relewise-product-search-overlay::part(overlay-container) {
...
}
relewise-product-search-overlay::part(overlay-title) {
...
}
relewise-search-bar::part(input) {
...
}Scroll position
When the user navigates to another page or leaves the site, the component will by default not remember where the user last scrolled to.
This can be toggled to do so, to ensure a smooth transition when the user returns back to the site.
This setting is part of the configuration supplied to the useSearch function.
useSearch({
rememberScrollPosition: true
});Variant Request Settings
This allows you to control how many variants are returned per product and how they are sorted for both the search overlay and the product search.
This setting is part of the configuration supplied to the useSearch function.
useSearch({
variantRequestSettings: builder => builder
.setMaxVariantsPerProduct(1)
.setSorting('ByRelevance'),
});maxVariantsPerProduct can be 0 for product-only results, 1 for one selected variant per product, or 2+ for multiple variants per product. Sorting defaults to GroupedByProduct; use ByRelevance when concrete variants should be ordered by variant-level relevance.
The explodedVariants option is deprecated. Existing configurations remain supported and are mapped to maxVariantsPerProduct, but variantRequestSettings takes precedence when both options are provided.
Retail Media
Retail media can be requested for product search requests by configuring it through useRetailMedia.
The product search and Universal Search components' target attributes select the retail media configuration for their product search requests. The retail media location is not related to a component's displayed-at-location attribute.
useRetailMedia(builder => builder
.variation({ key: 'MOBILE', minWidth: 0 })
.variation({ key: 'TABLET', minWidth: 768 })
.variation({ key: 'DESKTOP', minWidth: 1024 })
.selectedDisplayAdProperties({
displayName: true,
allData: true,
clickedByUserInfo: false,
})
.templates({
retailMediaSponsoredLabel: (product, { html }) => html`<span>Sponsored</span>`,
retailMediaDisplayAd: (displayAd, { html }) => html`<span>${displayAd.result.name}</span>`,
}));
registerSearchTarget('search-page', {
retailMedia: target => target
.location('SEARCH_RESULTS')
.placement('TOP_BANNER', placement => placement
.beforeResults())
.placement('IN_GRID', placement => placement
.atPosition({ position: 4 })),
});<relewise-product-search
displayed-at-location="Search Page"
target="search-page">
</relewise-product-search>
<relewise-universal-search
displayed-at-location="Universal Search"
target="search-page">
</relewise-universal-search>Variation keys are global for retail media requests. Configure each variation with the Relewise variation key and the min-width where it becomes active.
The min-width can be overwritten, and custom variation names can be configured by passing the key and min-width together:
useRetailMedia(builder => builder
.variation({ key: 'MOBILE', minWidth: 0 })
.variation({ key: 'TABLET', minWidth: 700 })
.variation({ key: 'DESKTOP', minWidth: 1100 })
.variation({ key: 'WIDE', minWidth: 1440 }));Retail media keys are passed directly to Relewise and must exactly match the location, variation, and placement keys configured in My Relewise. The component warns and skips locally incomplete configurations, duplicate placements, and invalid placement positions. A non-empty but incorrect key is sent to Relewise and typically results in no retail media being returned for that key.
Whether a placement returns sponsored products, display ads, or both is configured in Relewise backoffice.
Location and placement settings belong to the targeted search configuration:
registerSearchTarget('search-page', {
retailMedia(builder) {
builder
.location('SEARCH_RESULTS')
.placement('IN_GRID', placement => placement
.atPosition({ position: 4 }));
},
});Display ad and sponsored label rendering can be overwritten with Lit templates in the retail media configuration:
useRetailMedia(builder => builder
.templates({
retailMediaSponsoredLabel: (product, { html }) => html`<span>Sponsored</span>`,
retailMediaDisplayAd: (displayAd, { html }) => html`<span>${displayAd.result.name}</span>`,
}));Retail media results are rendered by <relewise-retail-media-tile>. Sponsored products use the configured product tile template and include a Sponsored label by default. retailMediaSponsoredLabel replaces that label and may be asynchronous. Display ads are skipped unless the synchronous retailMediaDisplayAd template is configured. Use an anchor in the display-ad template when the component should automatically track the display-ad click.
Retail media rendering is based on the configured placement position. atPosition is one-based, so position 4 makes the retail media result the fourth item in the product grid:
beforeResults()afterResults()atPosition({ position: 4 })
The same placement behavior is used by Product Search, collection/category pages that use Product Search with an empty term, and the products tab in Universal Search. Retail media does not change the organic hit count or load-more pagination.
Retail media rendering exposes these CSS parts through Product Search, Product Search Results, and Universal Search:
retail-media-productretail-media-display-adretail-media-product-tilesponsored-labeldisplay-ad
The default sponsored label can be styled with these CSS custom properties:
--relewise-retail-media-sponsored-label-background--relewise-retail-media-sponsored-label-border-radius--relewise-retail-media-sponsored-label-color--relewise-retail-media-sponsored-label-font-size--relewise-retail-media-sponsored-label-inset-block-start--relewise-retail-media-sponsored-label-inset-inline-start--relewise-retail-media-sponsored-label-padding
Facets
By default the component will not render any facets.
To start doing so, include your facet configuration in the useSearch function.
The label will be displayed at the top of the facet card.
relewise-facets manages its own responsive filter toggle by default. Add the expanded attribute when an outer layout owns that presentation and the facet content should always render without the internal toggle. Universal Search uses this mode inside its facet rail and drawer; the default Product Search behavior is unchanged.
useSearch({
facets: {
product(builder) {
builder
.addFacet((f) => f.addBrandFacet(), { heading: 'Brands' })
.addFacet((f) => f.addCategoryFacet('ImmediateParent'), { heading: 'Categories' })
.addFacet((f) => f.addSalesPriceRangeFacet('Product'), { heading: 'Sales Price' });
},
}
});Product, content, and product-category DataObject facets render their nested scalar facets recursively. Selections use the complete object path in the URL, so equal nested keys in different objects remain independent. When an object has multiple visible child facets, each heading includes the configured heading and the child's key.
useSearch({
facets: {
product(builder) {
builder.addFacet(
facet => facet.addProductDataObjectFacet('brand_values', 'Product', nested =>
nested.addStringFacet('brand_name')),
{ heading: 'Brand' },
);
},
},
});Layout
To overwrite the layout of the components, include the components inside the relewise-product-search html tag.
Every tag inside the relewise-product-search html tag, will be rendered as regular html so you can expand the content as needed and create your own layout.
<relewise-product-search displayed-at-location="LOCATION">
<relewise-product-search-bar></relewise-product-search-bar>
<div>
<relewise-product-search-sorting></relewise-product-search-sorting>
</div>
<div>
<relewise-facets></relewise-facets>
<hr>
<h1>Results</h1>
<div>
<relewise-product-search-load-more-button direction="previous"></relewise-product-search-load-more-button>
<relewise-product-search-results></relewi