Overview
The recommendations widget renders one or more recommendation rows into your shop. The script is loaded once per page, and every row is its own block with its own type, heading and placement.
The product cards are the same ones the search uses: they take your UI design, colors, badges, ratings and variant pickers from the project configuration. You only maintain the look in one place.
A row without products – or one whose request fails – renders nothing at all: no heading, no empty placeholder. Your page layout stays as it is.
Block types
Four types, each placeable on its own. Similar and complementary products need a source product, the other two do not.
- similar Product page
- Products similar to the current one, meaning alternatives for the same buying intent.
- complementary Product page
- Products that go with the current one and are typically bought together, meaning accessories and add-ons.
- bestseller Any page
- The products with the most conversions in the project, per language.
- recently_viewed Any page
- The products the visitor viewed most recently in their browser, newest first. Requires the visitor's analytics consent.
Shopify
On Shopify the Mandelbaum app ships two theme blocks, so there is no snippet to install.
- Install the Mandelbaum app in your shop and connect the project.
- In the theme editor, add the “Recommendations” block to your product page. It shows similar and/or complementary products for the current product.
- On every other page, add the “Recommendations (general)” block and pick bestsellers or recently viewed there.
- Set the heading, the number of products, the visible cards and the heading style directly in the theme editor.
Embedding
Without Shopify you embed the script yourself. There are two variants, both read their configuration from data attributes and both can be combined on the same page.
Variant 1 – by selector
You place empty containers in your template and point at them with data-similar-selector, data-bestseller-selector and so on: one attribute per row, on the script tag. The widget renders its row into the matched element. A selector that matches nothing is skipped.
html
<div id="pdp-similar"></div>
<div id="home-bestsellers"></div>
<script
src="https://mandelbaum.ai/recommendations-ui.js"
data-project-host="your-shop.example.com"
data-project-language="de"
data-product-url="https://your-shop.example.com/products/trail-shoe"
data-similar-selector="#pdp-similar"
data-similar-heading="Das könnte Ihnen auch gefallen"
data-bestseller-selector="#home-bestsellers"
data-bestseller-heading="Topseller"
data-limit="8"
data-columns="4"
async
></script>Variant 2 – by container
You place a div with data-mandelbaum-recommendations exactly where the rows should appear and configure them on that container. One container can show similar and complementary products together; for bestsellers or recently viewed you set data-type.
html
<div
data-mandelbaum-recommendations
data-product-url="https://your-shop.example.com/products/trail-shoe"
data-show-similar="true"
data-show-complementary="true"
data-heading="Das könnte Ihnen auch gefallen"
data-limit="8"
data-columns="4"
></div>
<script
src="https://mandelbaum.ai/recommendations-ui.js"
data-project-host="your-shop.example.com"
data-project-language="de"
async
></script>Attributes
Every attribute is optional as long as the defaults fit. data-project-host and data-project-language always go on the script tag, everything else goes wherever the block is configured.
| Attribute | Default | Read from | Description |
|---|---|---|---|
| data-project-host | location.origin | Script tag | Selects the project. Only needed when the script does not run on the shop's own domain, for example in a preview. |
| data-project-language | <html lang> | Script tag | Language for the configuration and the products. Without it the language is resolved from the page's lang attribute and then from the URL. |
| data-product-url | location.href | both | The product similar and complementary products are looked up for. The default is the current page, which is usually right on a product page. |
| data-<type>-selector | — | Script tag | CSS selector of the element the row of this type is rendered into. <type> is similar, complementary, bestseller or recently-viewed. |
| data-<type>-heading | — | Script tag | Heading of the row of this type. Without it no heading is rendered. |
| data-type | — | Container | Type of a general container block, bestseller or recently_viewed. |
| data-show-similar | false | Container | Set to true to show the row of similar products in the container. |
| data-show-complementary | false | Container | Set to true to show the row of complementary products in the container. |
| data-heading | — | Container | Heading for the rows of this container. |
| data-block-id | — | Container | Becomes part of the id of the rendered element so your theme can target a single row. |
| data-limit | 10 | both | Products per row. |
| data-columns | 4 | both | Cards visible at once at full width. Narrow screens show fewer and the row scrolls horizontally. |
| data-heading-color | — | both | Heading color as a hex value. Without it the heading inherits your theme's color. |
| data-heading-font-size | 20 | both | Heading font size in pixels. |
| data-heading-font-weight | 600 | both | Heading font weight, for example 400, 600 or 700. |
Invalid or non-positive numbers fall back to the default. Unknown attributes are ignored.
Styling
Recommendation cards are the same component as the search result cards and take their appearance from the same project configuration.
- Colors, radii, font sizes, badges, ratings and variant pickers come from your project's UI designer, matching the language of the page.
- Your own CSS from the UI designer is applied to the recommendation rows as well, so the cards look identical to the search cards.
- The only per-block styling is the heading – color, font size and font weight – so it matches the other section headings in your shop.
- All cards in a row share the same height. If the products do not fit the available width, the row scrolls horizontally with arrows on its edges.
Recently viewed
This row is based entirely on the visitor's browser. Visited pages are stored locally, the widget sends those URLs to Mandelbaum and gets the matching products back. Anything that is not a product of the project is ignored.
Visits are stored and read only with analytics consent, indicated by the mb_analytics_consent=1 cookie. Without consent the row stays empty and therefore renders nothing.
At most 20 pages are kept for 30 days, newest first, in localStorage under mb_recently_viewed. The product currently being viewed never appears in its own row.
Click tracking
Recommendation clicks are measured like search clicks and show up in the analytics as their own source, including the block type and the product the visitor clicked away from.
The product URLs the widget returns are signed tracking URLs and have to be used unchanged. Links you build yourself cannot be attributed.
Recommendation clicks do not count towards the search click-through rate. Conversions are attributed – via the Shopify pixel or the tracking API – to the row the visitor came from.
Rules
Recommendations honor your project's rules, so the same products are excluded and preferred as in the search.
- Exclusion rules apply to all four block types: excluded products appear in no recommendation row.
- Reranking rules apply to similar and complementary products and shift the order within the row. Rules that act on the search term have no effect, because there is no search term.
- Bestsellers and recently viewed have a fixed order – conversions and visit history respectively – and are not reordered on top of that.