Recombee Docs
Visit recombee.comStart Free
docs20User Documentation
adminuiAdmin UI
reql32ReQL
codeAPI Clients & Integrations
cookhatScenario Recipes
suitcaseMisc

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.

note20
Client-side SDK

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:

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):

Copy
<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.

Copy
<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:

Copy
npm install recombee-js-api-client
Copy
yarn install recombee-js-api-client
Copy
pnpm install recombee-js-api-client
Copy
bun install recombee-js-api-client

Afterwards, you can import the recombee object as follows:

Copy
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.

Copy
// 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.

Copy
// 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:

Copy
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.

Copy
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
Copy
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:

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.

PromiseCallback
On successReturn value is a Response objecterr = null, res = Response
On errorThrows an Errorerr = Error, res = undefined
Copy
// 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...
	});
Copy
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 full-text search is requested in the same way as recommendations:

Copy
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...
	});
Copy
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.

Copy
// 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:

ErrorCause
ApiErrorBase class for all errors
ResponseError extends ApiErrorThe API returned an error code (e.g. invalid parameter)
TimeoutError extends ApiErrorRequest 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:

For this tutorial, we'll use a sample Google Merchant product feed. You can find the sample file at this URL:

Copy
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:

index.html
<!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>
main.js
// 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:

index.html
<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>
main.js
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).

note20
Note

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.

© Copyright 2025, Recombee s.r.o
docs.recombee.com