Carousel Widget (JS)
A Vanilla JS widget that displays a horizontal scroll of recommended items, designed to increase engagement through visually appealing item rotation.
Use this library when you want to display a widget without using a transpiler
like Babel and without using JSX. This library exports a htm
HTML factory
to assemble custom elements of the widget.
This widget library is version 0.1.12 and the API can change. Please specify exact version when installing.
Installation
Install @recombee/carousel-widget-js@0.1.12
and recombee-js-api-client
packages using your preferred NPM package manager. This example is using
pnpm
.
pnpm add @recombee/carousel-widget-js@0.1.12 recombee-js-api-client
Always remember to apply the default CSS file distributed alongside the widget library, as shown in the examples.
Client Initialization
The widget loads recommendation data using Recombee API Client. Here is how to initialize the client with necessary configuration for a specific database:
import { } from "recombee-js-api-client";
const = "[database-id]";
const = "[database-public-token]";
const = "[database-region]";
export const = new (, , {
: ,
});
The Database Public Token can be found in the Admin UI Database Settings Page.
The widget also needs to be provided a createRequest
function, which
instantiates a client request class to define which data to pull from the
database. Use Scenario ID which can be found on Admin GUI
Database Scenarios Page.
Please ensure that you provide the user ID (typically obtained from your existing user tracking system), along with other relevant parameters - such as an item ID or Item Segment ID - depending on the specific type of recommendation request. See the Providing User ID section for details on how to obtain user ID in specific cases.
Providing User ID
Each visitor of your website should be identified by a user identificator
(userId
) to correlate user activity and deliver best possible
recommendation performance. The userId
should preferrably originate from
your user's account details when the user is authenticated or as some
session-persistent random ID when they are anonymous. The SDK provides
utility which generates random user id and saves it to a cookie to cover the
latter case:
import { type } from "@recombee/carousel-widget-react";
import { } from "recombee-js-api-client";
import { } from "@recombee/carousel-widget-react";
let : string | undefined;
if (authenticatedUserId) {
= authenticatedUserId;
} else {
= .();
}
const : = ({ }) => {
const = "recommend-items-to-user";
return new (, , {
: ,
: true,
: true,
});
};
Basic Example
The widget in this example uses the DefaultItem component to render each recommendation in a consistent layout.
The resulting widget is inserted into the element specified by the
container
field.
Values of the recommended items - such as title, image URL, or link URL - are
obtained from the API response and accessed via props.result?.values
.
Ensure that returnProperties: true is set in the request, and optionally use includedProperties to control which item properties are returned.
import {
,
,
,
,
,
} from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
({
: "#widget-root",
: ,
: ,
: "gap-4 p-6",
: "min-w-[240px] min-h-[260px]",
: () =>
`<${}
href=${(
`${.?.?.link}`,
..,
)}
image=${`<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>`}
labelContent=${`${.?.?.genres?.join(", ")}`}
title=${`${.?.?.title}`}
highlightedContent=${`${.?.?.year}`}
/>`,
});
The addRecommIdQueryParam utility function is used to append the
recommendation ID to the item's URL as the recombee_recomm_id
query
parameter.
This enables you to report successful (clicked) recommendations back to Recombee for improved tracking and performance optimization.
Custom CSS
Recombee Widgets are designed to be styling-agnostic. You can fully customize their appearance using your own CSS by passing class names through customization properties.
In these docs examples, we use utility classes from Tailwind CSS for styling.
Class names for internal elements and custom components are passed as props and applied by the widget during rendering. The default structure of the Basic Example widget is illustrated below (pseudo-code):
<div class="{className}">
<div class="{contentClassName}">
<div class="{itemWrapperClassName}">
<ItemComponent />
</div>
<div class="{itemWrapperClassName}">
<ItemComponent />
</div>
<div class="{itemWrapperClassName}">
<ItemComponent />
</div>
... more items ...
</div>
<ArrowComponent arrowDirection="left" />
<ArrowComponent arrowDirection="right" />
</div>
This is handy to understand how to customize the widget to full potential.
Setting own classes
import {
,
,
,
,
,
} from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
({
: "#widget-root",
: ,
: ,
:
"overflow-hidden rounded-lg border-[#ededed] bg-white text-[#282b30] dark:border-none dark:bg-transparent dark:text-white",
: "gap-4 p-6",
: "min-w-[240px] min-h-[260px]",
: () =>
`<${}
classNameDisableBase
className="border-b border-slate-600"
contentWrapperClassName="text-center"
href=${(
`${.?.?.link}`,
..,
)}
image=${`<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>`}
labelContent=${`${.?.?.genres?.join(", ")}`}
title=${`${.?.?.title}`}
highlightedContent=${`${.?.?.year}`}
/>`,
});
Custom Templates
Recombee Widgets support full customization of internal components such as the appearance of the recommended items.
You can provide your own components via props like ItemComponent to control the structure, styling, and behavior of the widget.
This flexibility allows you to adapt the widget's appearance and functionality to match your design and user experience requirements.
Custom Item
import { , , } from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
({
: "#widget-root",
: ,
: ,
: "gap-4 p-6",
: "min-h-[290px] w-[200px]",
: () =>
`<div
className="overflow-hidden rounded-lg border-[#ededed] bg-white text-[#282b30] dark:border-none dark:bg-transparent dark:text-white"
>
<div className="relative overflow-hidden bg-cover bg-no-repeat">
<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>${.?.?.["genres"]?.includes("drama") &&
`<div
className="absolute top-3 left-3 bg-[#3f91ff] px-2 text-xs/[1.67] font-semibold text-white"
>
Drama
</div>`}${.?.?.["genres"]?.includes(
"science_fiction",
) &&
`<div
className="absolute top-3 left-3 bg-[#36c696] px-2 text-xs/[1.67] font-semibold text-white"
>
Sci-Fi
</div>`}
</div>
<div className="p-3">
<div
className="mb-1 line-clamp-4 overflow-hidden text-[14px]/[1.43] text-nowrap text-ellipsis text-[#80868f]"
>
${`${.?.?.genres?.join(", ")}`}
</div>
<div className="text-md mb-1 overflow-hidden text-nowrap text-ellipsis">
${`${.?.?.title}`}
</div>
<div className="line-clamp-4 pb-3 text-base text-[#3f91ff]">
${`${.?.?.year}`}
</div>
<button
className="w-full rounded-lg border border-[#ededed] py-2 text-center text-[14px]/[1.43] font-medium text-[#80868f]"
>
Play
</button>
</div>
</div>`,
});
Custom Arrows
import {
,
,
,
,
,
} from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
({
: "#widget-root",
: ,
: ,
: "gap-4 p-6",
: "min-h-[400px] w-[400px]",
: () => {
if (. === "left" && ...) {
return `<button
className="absolute top-1/2 left-4 -translate-y-6 rounded-lg rounded-sm border border-[#ededed] bg-white px-3 py-2 text-center text-[14px]/[1.43] font-medium text-[#80868f]"
type="button"
onClick=${...}
>
prev
</button>`;
}
if (. === "right" && ...) {
return `<button
className="absolute top-1/2 right-4 -translate-y-6 rounded-lg rounded-sm border border-[#ededed] bg-white px-3 py-2 text-center text-[14px]/[1.43] font-medium text-[#80868f]"
type="button"
onClick=${...}
>
next
</button>`;
}
},
: () =>
`<${}
href=${(
`${.?.?.link}`,
..,
)}
image=${`<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>`}
labelContent=${`${.?.?.genres?.join(", ")}`}
title=${`${.?.?.title}`}
highlightedContent=${`${.?.?.year}`}
/>`,
});
Full Customization
import {
,
,
,
,
,
} from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
function (: any) {
const = `w-full rounded-lg border border-[#ededed] py-2 px-3 text-center text-[14px]/[1.43] font-medium text-[#80868f]`;
return `<button
className=${(, {
"opacity-50": .disabled,
})}
...${}
/>`;
}
({
: "#widget-root",
: ,
: ,
: () => null,
: () =>
`<div className="p-4"><${} ...${} contentClassName="gap-1" itemWrapperClassName="min-h-[240px] w-[200px]"/><div className="flex justify-end gap-2 pt-4"><div className="flex gap-2"><${} disabled=${!
...} onClick=${
...
}>PREV</${}><${} disabled=${!.
..} onClick=${
...
}>NEXT</${}></div></div></div>`,
: () =>
`<div
className="overflow-hidden rounded-lg border-[#ededed] bg-white text-[#282b30] dark:border-none dark:bg-transparent dark:text-white"
>
<div className="relative overflow-hidden bg-cover bg-no-repeat">
<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>${.?.?.["genres"]?.includes("drama") &&
`<div
className="absolute top-3 left-3 bg-[#3f91ff] px-2 text-xs/[1.67] font-semibold text-white"
>
Drama
</div>`}${.?.?.["genres"]?.includes(
"science_fiction",
) &&
`<div
className="absolute top-3 left-3 bg-[#36c696] px-2 text-xs/[1.67] font-semibold text-white"
>
Sci-Fi
</div>`}
</div>
<div className="p-3">
<div
className="mb-1 line-clamp-4 overflow-hidden text-[14px]/[1.43] text-nowrap text-ellipsis text-[#80868f]"
>
${`${.?.?.genres?.join(", ")}`}
</div>
<div className="text-md mb-1 overflow-hidden text-nowrap text-ellipsis">
${`${.?.?.title}`}
</div>
<div className="line-clamp-4 pb-3 text-base text-[#3f91ff]">
${`${.?.?.year}`}
</div>
<button
className="w-full rounded-lg border border-[#ededed] py-2 text-center text-[14px]/[1.43] font-medium text-[#80868f]"
>
Play
</button>
</div>
</div>`,
});
Overriding Base Classes
Some base styles are always applied to ensure the widget maintains the structural shape of a carousel.
However, these can be disabled or overridden if needed. Use the CarouselWidgetProps.classNameDisableDefault and related options to opt out of default styling.
import {
,
,
,
,
,
} from "@recombee/carousel-widget-js";
import "@recombee/carousel-widget-js/dist/styles.css";
({
: "#widget-root",
: ,
: ,
: true,
:
"rb:no-scrollbar flex min-h-[420px] snap-x snap-mandatory content-stretch gap-1 overflow-x-auto p-6",
: true,
:
"min-h-[260px] flex min-w-full flex-grow basis-full snap-center",
: () =>
`<${}
href=${(
`${.?.?.link}`,
..,
)}
image=${`<${}
src=${`${.?.?.images?.[0]}`}
width=${600}
height=${400}
/>`}
labelContent=${`${.?.?.genres?.join(", ")}`}
title=${`${.?.?.title}`}
highlightedContent=${`${.?.?.year}`}
/>`,
});
API Reference
CarouselWidget
Carousel Widget initialization function
CarouselWidgetOptions
Carousel Widget configuration options.
Properties
container
CSS Selector to target the element where the widget should be inserted.
createRequest
Request factory function. See Quick Example or visit API Reference for overview of available requests.
onRecommResponse
Callback function allowing to intercept and inspect recommendation request+response made by widget.
deduplicationPartitionKey
A string key specifying a group of widgets, in which recommendation results will be deduplicated. By default, all widgets belong to a single group so all results from the same database are deduplicated.
initialItemsCount
Number of items to load immediately. Adjust to have more items loaded ahead of user scrolling.
classNameDisableDefault
Disables default classes of widget wrapper element.
There are some default class names with essential styles applied to the widget wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
contentClassNameDisableDefault
Disables default classes of content wrapper element.
There are some default class names with essential styles applied to the content wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
itemWrapperClassNameDisableDefault
Disables default classes of item wrapper element.
There are some default class names with essential styles applied to the item wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
ItemComponent
A component rendering a single recommended item.
ArrowComponent
A component rendering either left or right carousel arrow
CarouselComponent
Component responsible for rendering the widget markup.
Example in which the passed component wraps the default carousel component with additional custom HTML.
This property also allows to fully cutomize the carousel HTML in extreme cases.
DefaultItem
Default Item component provided for basic usage.
DefaultItemProps
Recommended item component properties.
Properties
classNameDisableBase
Disables default classes of item wrapper element.
There are some default class names with essential styles applied to the item wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
imageWrapperClassName
Custom classes of item image wrapper element. See Custom CSS.
imageWrapperClassNameDisableBase
Disables default classes of item image wrapper element.
There are some default class names with essential styles applied to the item image wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
result
A single item recommedation.
href
Item link URL.
image
Item Image element.
labelContent
Item content above title. Sets the entire content of an item aside from an image.
labelContentWrapperClassName
Custom classes of label content wrapper element. See Custom CSS.
labelContentWrapperClassNameDisableBase
Disables default classes of label content wrapper element.
There are some default class names with essential styles applied to the label content wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
title
Item title.
titleWrapperClassNameDisableBase
Disables default classes of title wrapper element.
There are some default class names with essential styles applied to the title wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
highlightedContent
Item content under title. Sets the entire content of an item aside from an image.
highlightedContentWrapperClassName
Custom classes of highlighted content wrapper element. See Custom CSS.
highlightedContentWrapperClassNameDisableBase
Disables default classes of highlighted content wrapper element.
There are some default class names with essential styles applied to the highlighted content wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
bottomContent
Any custom content to display at the bottom of the item.
ItemImage
Item image component
ItemImageProps
Item Image properties
Properties
src
Image URL
missingImageSrc
URL of an image to display when the main image could not be loaded.
className
Image wrapper class name
imgClassName
Image class name
width
Image width in pixels
height
Image height in pixels
verticalAlignment
Image vertical alignment
horizontalAlignment
Image horizontal alignment
fittingAlgorithm
Image fitting algorithm
addRecommIdQueryParam
Utility function to append recombee_recomm_id
parameter to an url string.
For usage in widget template to construct item link URL.
Recommendation
Single recommendation item
Properties
id
Item ID
values
Item properties
CreateRequestFunction
Factory for creating Recombee API Request to load data into a Widget.
FetchContentOptions
CreateRequestFunction parameter
Properties
count
Number of items to fetch for the widget. Pass it to the appropriate Request constructor.
CarouselWidgetProps
Carousel Widget React Component configuration properties
Properties
createRequest
Request factory function. See Quick Example or visit API Reference for overview of available requests.
onRecommResponse
Callback function allowing to intercept and inspect recommendation request+response made by widget.
deduplicationPartitionKey
A string key specifying a group of widgets, in which recommendation results will be deduplicated. By default, all widgets belong to a single group so all results from the same database are deduplicated.
initialItemsCount
Number of items to load immediately. Adjust to have more items loaded ahead of user scrolling.
classNameDisableDefault
Disables default classes of widget wrapper element.
There are some default class names with essential styles applied to the widget wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
contentClassNameDisableDefault
Disables default classes of content wrapper element.
There are some default class names with essential styles applied to the content wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
itemWrapperClassNameDisableDefault
Disables default classes of item wrapper element.
There are some default class names with essential styles applied to the item wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
ItemComponent
A component rendering a single recommended item.
ArrowComponent
A component rendering either left or right carousel arrow
CarouselComponent
Component responsible for rendering the widget markup.
Example in which the passed component wraps the default carousel component with additional custom HTML.
This property also allows to fully cutomize the carousel HTML in extreme cases.
CarouselWidgetState
Exposes internal state data of the widget to be used in customizable components
Properties
wrapperRef
React ref necessary to control the carousel wrapper element. See Customization Example.
contentRef
React ref necessary to control the carousel content element. See Customization Example.
items
Array of items to show in the carousel.
recommId
Id of recommendation response from which the items originated.
leftArrow
Current state of left Carousel arrow
rightArrow
Current state of right Carousel arrow
DefaultCarousel
Default visual component used to render carousel container
DefaultCarouselProps
Carousel Properties
Properties
state
Carousel state.
classNameDisableDefault
Disables default classes of widget wrapper element.
There are some default class names with essential styles applied to the widget wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
contentClassNameDisableDefault
Disables default classes of content wrapper element.
There are some default class names with essential styles applied to the content wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
itemWrapperClassNameDisableDefault
Disables default classes of item wrapper element.
There are some default class names with essential styles applied to the item wrapper element. This setting disables them as an escape hatch for customization. See Custom CSS.
ItemComponent
A component rendering a single recommended item.
ArrowComponent
A component rendering either left or right carousel arrow
DefaultCarouselArrow
Default Carousel arrow component
CarouselArrowProps
Carousel Arrow configuration options
Properties
arrowDirection
The direction of an arrow to render.
state
Carousel state.