JavaScript API Client
This library allows you to request recommendations and send interactions between users and items (such as views, bookmarks, or purchases) to Recombee. It is a thin wrapper around the Recombee API and provides a simple way to interact with it.
This SDK is designed for use in browser-based or other client-side applications, including frameworks like React Native and NativeScript.
For server-side integration with the Recombee API, use our dedicated Node.js library or other available server-side SDKs.
To use this client-side SDK in a full-stack framework (e.g., Nuxt or Next.js), additional configuration is required. See Usage in Full-stack frameworks for more information.
For security reasons, it is not possible to change the item catalog, such as the properties of items, using this SDK. To send your Catalog to Recombee, use one of the following methods:
- Use one of our server-side SDKs, for example using a script which runs periodically (see Managing Item Catalog for more details),
- Or set up a Catalog Feed in the Admin UI.
Install
There are two ways to include the library in your project:
1. <script> tag:
You can add the following script tag to your HTML file (the content is served by jsDelivr):
<script src="https://cdn.jsdelivr.net/npm/recombee-js-api-client@5.0.1/dist/recombee-api-client.min.js"></script>
If you require, you can download recombee-api-client.min.js and host it on your site or CDN.
<script src="path/to/recombee-api-client.min.js"></script>
After this script is included, you can access the API Client using the global recombee
object.
2. Package managers:
Alternatively, you can install the SDK via a package manager:
npm install recombee-js-api-client
yarn install recombee-js-api-client
pnpm install recombee-js-api-client
bun install recombee-js-api-client
Afterwards, you can import the recombee
object as follows:
import recombee from 'recombee-js-api-client'
// or
const recombee = require('recombee-js-api-client');
The library ships with types, so you should get autocompletion in your IDE out of the box. If you're using TypeScript, it should recognize these correctly and warn you about any type errors.
Configure
In order to use the API, you will need to create an instance of the ApiClient
class. You will need:
- the ID of your database,
- the public token.
You can find these in the Admin UI, in your Database's Settings page, under API ID & Tokens. Along with this information, you can also find the full code snippet for initializing the client, including the above-mentioned parameters.
Ideally, you should only have one instance of the ApiClient
in your application, as it is a lightweight object and can be reused for multiple requests.
Feel free to export it from a module and import it wherever you need it.
// Initialize the API client with the ID of your database and the associated PUBLIC token
export const client = new recombee.ApiClient('database-id', '...db-public-token...', {
region: 'us-west', // the region of your database (default: 'eu-west')
});
You can also set several optional parameters when initializing the client:
const client = new recombee.ApiClient('database-id', '...db-public-token...',
{
// Use this if you were assigned a custom URI by the Recombee Support team (default: none)
baseUri: 'custom-uri.recombee.com',
// Whether to use HTTPS - can be used for debugging (default: true)
useHttps: true,
// Whether to send the requests asynchronously (default: true)
async: true,
}
);
Send Interactions
After you have initialized the client, you can send interactions between users and items.
The individual interactions are classes within the recombee
object (e.g. recombee.AddBookmark
, recombee.AddPurchase
, etc.).
After you create an instance of the interaction, you can send it using the send
method of the client.
Each interaction has both mandatory and optional parameters.
The most important optional parameter is recommId
- the ID of the recommendation to which the interaction belongs.
Providing this ID allows you to track successful recommendations.
For more information, read about Reported Metrics.
For a full list of interactions, along with their parameters, refer either to the types in the library or the API Reference.
// Either create the interaction first and then send it
const bookmark = new recombee.AddBookmark('user-13434', 'item-256');
client.send(bookmark);
// Or send it directly
client.send(new recombee.AddCartAddition('user-4395', 'item-129', {
recommId: '23eaa09b-0e24-4487-ba9c-8e255feb01bb',
}));
client.send(new recombee.AddDetailView('user-9318', 'item-108'));
client.send(new recombee.AddPurchase('user-7499', 'item-750'));
client.send(new recombee.AddRating('user-3967', 'item-365', 0.5));
client.send(new recombee.SetViewPortion('user-4289', 'item-487', 0.3));
If you want to send multiple interactions at once, you can use the Batch
request:
const batch = new recombee.Batch([
new recombee.AddBookmark('user-13434', 'item-256'),
new recombee.AddCartAddition('user-4395', 'item-129', { cascadeCreate: true }),
new recombee.AddDetailView('user-9318', 'item-108'),
]);
client.send(batch);
You can then use the Promise (or callbacks) to handle any errors that may occur.
try {
await client.send(
new recombee.AddPurchase('user-14125', 'item-137', { cascadeCreate: true })
);
console.log('Purchase sent');
} catch (err) {
console.error('Error sending purchase:', err);
}
// or
client.send(
new recombee.AddPurchase('user-14125', 'item-137', { cascadeCreate: true })
).then(() => {
console.log('Purchase sent');
}).catch((err) => {
console.error('Error sending purchase:', err);
})
// Console: Purchase sent
client.send(
new recombee.AddPurchase('user-14125', 'item-137', { cascadeCreate: true }),
(err) => {
if (err) {
console.error('Error sending purchase:', err);
return;
}
console.log('Purchase sent');
}
);
// Console: Purchase sent
Get Recommendations
With an initialized client, you can also request recommendations.
There are multiple types of recommendations, such as:
- Recommend Items to User,
- Recommend Items to Item,
- Recommend Item Segments to User (these can be categories, genres, artists, etc.),
- or others.
Each recommendation request is a class within the recombee
object (e.g. recombee.RecommendItemsToUser
, recombee.RecommendItemsToItem
, etc.).
After you create an instance of the recommendation request, you can send it using the send
method of the client.
Promise | Callback | |
---|---|---|
On success | Return value is a Response object | err = null, res = Response |
On error | Throws an Error | err = Error, res = undefined |
// Get 5 recommendations related to 'item-356' for 'user-13434'
const response = await client.send(
new recombee.RecommendItemsToItem("item-356", "user-13434", 5)
);
// or
client
.send(new recombee.RecommendItemsToItem("item-356", "user-13434", 5))
.then(function (response) {
console.log(response);
// {
// recommId: 'f080784b-1e8b-4328-8d59-28d962301007',
// recomms: [
// {
// id: 'item-123',
// values: { title: 'Product 123', img_url: 'https://example.com/img123.jpg' }
// },
// {
// id: 'item-456',
// values: { title: 'Product 456', img_url: 'https://example.com/img456.jpg' }
// },
// ...
// ]
// }
})
.catch(function (err) {
console.error(err);
// use fallback...
});
const callback = function (err, res) {
if (err) {
console.error(err);
// use fallback ...
return;
}
console.log(res);
// {
// recommId: 'f080784b-1e8b-4328-8d59-28d962301007',
// recomms: [
// {
// id: 'item-123',
// values: { title: 'Product 123', img_url: 'https://example.com/img123.jpg' }
// },
// {
// id: 'item-456',
// values: { title: 'Product 456', img_url: 'https://example.com/img456.jpg' }
// },
// ...
// ]
// }
};
// Get 5 recommendations related to 'item-356' for 'user-13434'
client.send(new recombee.RecommendItemsToItem("item-356", "user-13434", 5), callback);
For a full list of request parameters and possible responses, visit the API Reference.
Personalized Search
Personalized full-text search is requested in the same way as recommendations:
const searchQuery = " ... search query from search field ....";
const response = await client.send(
new recombee.SearchItems("user-13434", searchQuery, 5)
);
// or
client
.send(new recombee.SearchItems("user-13434", searchQuery, 5))
.then(function (response) {
console.log(response);
// {
// recommId: 'f080784b-1e8b-4328-8d59-28d962301007',
// recomms: [
// {
// id: 'item-123',
// values: { title: 'Product 123', img_url: 'https://example.com/img123.jpg' }
// },
// {
// id: 'item-456',
// values: { title: 'Product 456', img_url: 'https://example.com/img456.jpg' }
// },
// ...
// ]
// }
})
.catch(function (err) {
console.error(err);
// use fallback...
});
const searchQuery = " ... search query from search field ....";
client.send(new recombee.SearchItems("user-13434", searchQuery, 5), callback);
Recommend Next Items
If you are implementing features like infinite scroll or pagination, you can use the RecommendNextItems
request to load recommendations progressively.
This means you can fetch the next set of recommended items without repeating the ones you have already displayed.
To use this functionality, you must provide the recommId
from the initial recommendation request.
For more details, see the Recommend Next Items documentation.
// Fetch the initial set of 5 recommendations for user-13434
const initialRecomms = await client.send(
new recombee.RecommendItemsToUser("user-13434", 5)
);
// Get the next 3 recommendations as user-13434 scrolls down
const nextRecomms = await client.send(
new recombee.RecommendNextItems(initialRecomms.recommId, 3)
// Use the recommId from the previous request ^
);
Optional parameters
Recommendation requests support various optional parameters to customize their behavior. For a comprehensive list, refer to the API Reference. Below is an example showcasing some commonly used parameters:
const response = await client.send(new recombee.RecommendItemsToUser('user-13434', 5,
{
// Scenarios help identify the context where recommendations are displayed
// and can be customized in the Admin UI at https://admin.recombee.com
scenario: 'homepage',
// Include detailed properties of the recommended items in the response
returnProperties: true,
// Specify which properties to include (requires returnProperties = true)
includedProperties: ['title', 'img_url', 'url', 'price'],
// Apply a ReQL filter to refine recommendations,
// e.g., "Recommend only items with a title that are in stock."
filter: "'title' != null AND 'availability' == \"in stock\""
// Note: You can define scenario-specific filters in the Admin UI.
}
));
Error Handling
The API client throws errors when an error occurs.
The possible errors are:
Error | Cause |
---|---|
ApiError | Base class for all errors |
ResponseError extends ApiError | The API returned an error code (e.g. invalid parameter) |
TimeoutError extends ApiError | Request timed out |
We are doing our best to provide a reliable service, but sometimes things can go wrong. For this reason, we recommend that you always handle exceptions and provide fallbacks in your application.
For example, when requesting recommendations, a fallback could be to display a generic set of items or an error message to the user.
Integration Example
1. Create a Recombee account
To follow this example, you'll need a Recombee account. If you don't already have one, you can sign up for free.
If you weren't invited to an existing Organization or Database, Recombee will automatically create one for you during registration.
2. Upload the Catalog
The next step is to upload your item catalog to Recombee. You can do this using one of the following methods:
- API-based upload: Follow the instructions in our Managing Item Catalog guide.
- Catalog Feed: Set up a feed in the Admin UI.
For this tutorial, we'll use a sample Google Merchant product feed. You can find the sample file at this URL:
https://raw.githubusercontent.com/recombee/js-api-client/refs/heads/master/examples/product_feed_sample.xml
After adding the feed to the Admin UI and waiting for it to process, you'll be able to see the uploaded items in the Items section of your Database.
3. Integrate Recombee into your website
Let's assume we want to show recommendations on the product page of item product-270
to a user with the ID user-1539
.
The following code example uses HTML and vanilla JavaScript to send the Detail View interaction of the product by the user and request 3 related items from the Recombee API:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Recombee Integration Example</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
</head>
<body>
<div class="container">
<div class="row">
<h1 class="my-5">Related products</h1>
<div class="col-md-12">
<div class="row align-items-stretch" id="relatedProducts">
<!-- Recommendations will be rendered here -->
</div>
</div>
</div>
</div>
<!-- Bootstrap UI -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"
></script>
<!-- Recombee API Client -->
<script src="https://cdn.jsdelivr.net/gh/recombee/js-api-client@5.0.0/dist/recombee-api-client.min.js"></script>
<!-- Our own implementation -->
<script src="./main.js"></script>
</body>
</html>
// A simple function for rendering a box with the recommended product
function showProduct(title, description, link, imageLink, price) {
return [
`<div class="col-md-4 text-center col-sm-6 col-xs-6">`,
` <div class="card h-100" style="min-height: 300px">`,
` <img src="${imageLink}" alt="Image of ${title}" class="card-img-top mt-2" style="max-height: 100px" />`,
` <div class="card-body d-flex flex-column">`,
` <h5 class="card-title"><a href="${link}">${title}</a></h5>`,
` <h6 class="card-subtitle mb-2 text-body-secondary">Price: <strong>$${price}</strong></h6>`,
` <p class="card-text flex-grow-1">${description}</p>`,
` <a href="${link}" class="btn btn-primary" role="button">See Details</a></p>`,
` </div>`,
` </div>`,
`</div>`,
].join("\n");
}
// Initialize client
const client = new recombee.ApiClient(
"js-client-example",
"dXx2Jw4VkkYQP1XU4JwBAqGezs8BNzwhogGIRjDHJi39Yj3i0tWyIZ0IhKKw5Ln7",
{ region: "eu-west" }
);
const itemId = "product-270";
const userId = "user-1539";
// Send Detail View
client.send(new recombee.AddDetailView(userId, itemId));
// Request recommended items
client
.send(
new recombee.RecommendItemsToItem(itemId, userId, 3, {
returnProperties: true,
includedProperties: [
"title",
"description",
"link",
"image_link",
"price",
],
filter: "'title' != null AND 'availability' == \"in stock\"",
scenario: "related_items",
})
)
.catch((err) => {
console.error("Could not load recomms: ", err);
})
.then((res) => {
// Show recommendations
const recomms_html = res.recomms
.map((r) => r.values)
.map((vals) =>
showProduct(
vals["title"],
vals["description"],
vals["link"],
vals["image_link"],
vals["price"]
)
);
document.getElementById("relatedProducts").innerHTML =
recomms_html.join("\n");
});
You should see something like this:

Notice how the properties returned by returnProperties
, in combination with includedProperties
, were used to show titles, images, descriptions and URLs.
Identifying users using Google Analytics
In order to achieve personalization, you need a unique identifier for each user.
One of the ways to achieve this can be using Google Analytics. You would need to add the following to the previous example:
<head>
<!-- Add the following to the end of <head>: -->
<!-- Load gtag.js asynchronously -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<!-- Optionally, define gtag in the HTML (quick approach) -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
</script>
</head>
const client = new recombee.ApiClient(...);
// Optional check: if you want to ensure gtag is defined
// (this is often not necessary if you define gtag in HTML as shown)
if (typeof gtag !== 'function') {
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
}
// Initialize GA4
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX'); // Replace with your GA4 measurement ID
gtag('get', 'G-XXXXXXXXXX', 'client_id', (clientId) => {
client.send(new recombee.AddDetailView(clientId, itemId));
client
.send(new recombee.RecommendItemsToUser(clientId, 3,
{
returnProperties: true,
includedProperties: ['title', 'description', 'link', 'image_link', 'price'],
filter: "'title' != null AND 'availability' == \"in stock\"",
scenario: 'homepage'
}),
)
.catch(...)
.then(...);
});
This example uses the Recommend Items to User API endpoint. You can use this recommendation type in various places, such as on your homepage.
Usage in Full-stack frameworks
By default, this client relies on the XMLHttpRequest object to send requests, which is not available in Node.js. This may lead to issues when sharing code between client-side and server-side environments (for example, in full-stack frameworks like Next.js, Nuxt.js, or SvelteKit).
To fix this issue, you can configure the client to use the Fetch API by setting the future_v6_fetch
parameter to true
during initialization:
const client = new recombee.ApiClient('database-id', '...db-public-token...', {
future_v6_fetch: true,
// other optional parameters...
});
This behavior will become the default in the next major version of the library (v6).
Using this setting requires support for Fetch and Promises within your environment. If you are using a polyfill, make sure it is loaded before the client is initialized.
The Fetch-based implementation also does not support the parameter async = false
, as Fetch requests are asynchronous by nature.