Examples and Use Cases
This page provides practical examples of how to use the Recommendations API for different scenarios.
Product Detail Page (PDP) Recommendations
- Request
- Response
- JavaScript
- React
GET https://<PA_END_POINT>/3.0/recommendations?currentUrl=https://www.example.com/product/12345&refId=12345&expandProductDetails=true
{
"recommendations": {
"route": {
"id": "pdp-route-id",
"name": "Product Detail Page Route",
"widgets": [
{
"id": "similar-items-widget-id",
"name": "Similar Items",
"slots": [
{
"label": "Similar Items Slot",
"tacticId": "similar-items-tactic",
"products": [
{
"refId": "product456",
"name": "Similar Product",
"description": "This is a similar product",
"isInStock": true,
"images": ["https://example.com/image1.jpg"],
"prices": [
{
"price": 49.99,
"code": "USD"
}
]
}
]
},
{
"label": "Similar Items Slot",
"tacticId": "similar-items-tactic",
"products": [
{
"refId": "product789",
"name": "Another Similar Product",
"description": "Another similar product description",
"isInStock": true,
"images": ["https://example.com/image2.jpg"],
"prices": [
{
"price": 59.99,
"code": "USD",
"discountPrice": 39.99
}
]
}
]
}
]
},
{
"id": "frequently-bought-together-widget-id",
"name": "Frequently Bought Together",
"slots": [
{
"label": "Frequently Bought Together Slot",
"tacticId": "bought-together-tactic",
"products": [
{
"refId": "accessory123",
"name": "Compatible Accessory",
"isInStock": true,
"images": ["https://example.com/accessory.jpg"],
"prices": [
{
"price": 19.99,
"code": "USD"
}
]
}
]
},
{
"label": "Frequently Bought Together Slot",
"tacticId": "bought-together-tactic",
"products": [
{
"refId": "accessory456",
"name": "Another Accessory",
"isInStock": true,
"images": ["https://example.com/accessory2.jpg"],
"prices": [
{
"price": 24.99,
"code": "USD"
}
]
}
]
}
]
}
]
}
}
}
async function getProductRecommendations(productId) {
// Use the actual current URL from the browser
const params = new URLSearchParams({
currentUrl: window.location.href, // Use actual current URL
refId: productId, // Set product ID as refId parameter
expandProductDetails: 'true'
});
const response = await fetch(
`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`,
{
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
// Process and display recommendations
if (data.recommendations?.route?.widgets) {
data.recommendations.route.widgets.forEach(widget => {
console.log(`Widget: ${widget.name}`);
widget.slots.forEach(slot => {
console.log(`- Slot: ${slot.label}`);
slot.products.forEach(product => {
console.log(` - Product: ${product.name} (${product.refId})`);
// Display product information on the page
});
});
});
}
}
// Call the function with a product ID
getProductRecommendations('12345');
import { useState, useEffect } from 'react';
function ProductRecommendations({ productId }) {
const [recommendations, setRecommendations] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchRecommendations() {
try {
// Use the actual current URL from the browser
const params = new URLSearchParams({
currentUrl: window.location.href, // Use actual current URL
refId: productId, // Set product ID as refId parameter
expandProductDetails: 'true'
});
const response = await fetch(
`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`,
{
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
// Extract products from all widgets and slots
const products = [];
if (data.recommendations?.route?.widgets) {
data.recommendations.route.widgets.forEach(widget => {
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
products.push({
widgetName: widget.name,
slotLabel: slot.label,
products: slot.products
});
}
});
});
}
setRecommendations(products);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchRecommendations();
}, [productId]);
if (loading) return <div>Loading recommendations...</div>;
if (error) return <div>Error loading recommendations: {error}</div>;
return (
<div className="product-recommendations">
{recommendations.map((section, idx) => (
<div key={idx} className="recommendation-section">
<h3>{section.widgetName}</h3>
<h4>{section.slotLabel}</h4>
<div className="product-carousel">
{section.products.map(product => (
<div key={product.refId} className="product-card">
{product.images && product.images[0] && (
<img src={product.images[0]} alt={product.name} />
)}
<h4>{product.name}</h4>
{product.prices && product.prices[0] && (
<div className="price">
{product.prices[0].discountPrice ? (
<>
<span className="original-price">${product.prices[0].price}</span>
<span className="discount-price">${product.prices[0].discountPrice}</span>
</>
) : (
<span>${product.prices[0].price}</span>
)}
</div>
)}
<button>Add to Cart</button>
</div>
))}
</div>
</div>
))}
</div>
);
}
export default ProductRecommendations;
Shopping Cart Recommendations
- Request
- Response
- JavaScript
GET https://<PA_END_POINT>/3.0/recommendations?currentUrl=https://www.example.com/cart&productsInCart[0]=product123&productsInCart[1]=product456&expandProductDetails=true
{
"recommendations": {
"route": {
"id": "cart-route-id",
"name": "Shopping Cart Route",
"widgets": [
{
"id": "complete-your-purchase-widget-id",
"name": "Complete Your Purchase",
"slots": [
{
"label": "Complete Your Purchase Slot",
"tacticId": "complete-purchase-tactic",
"products": [
{
"refId": "accessory123",
"name": "Related Accessory",
"description": "This accessory works with items in your cart",
"isInStock": true,
"images": ["https://example.com/accessory1.jpg"],
"prices": [
{
"price": 29.99,
"code": "USD"
}
]
}
]
},
{
"label": "Complete Your Purchase Slot",
"tacticId": "complete-purchase-tactic",
"products": [
{
"refId": "accessory456",
"name": "Another Accessory",
"description": "Another accessory for your cart",
"isInStock": true,
"images": ["https://example.com/accessory2.jpg"],
"prices": [
{
"price": 34.99,
"code": "USD"
}
]
}
]
}
]
}
]
}
}
}
function getCartRecommendations(cartItems) {
// Build parameters
const params = new URLSearchParams();
// Use the actual current URL from the browser
params.append('currentUrl', window.location.href);
// Add cart items
cartItems.forEach((item, index) => {
params.append(`productsInCart[${index}]`, item);
});
params.append('expandProductDetails', 'true');
// Make API request
fetch(`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.recommendations?.route?.widgets) {
// Process recommendations
const recommendedProducts = [];
data.recommendations.route.widgets.forEach(widget => {
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
slot.products.forEach(product => {
recommendedProducts.push(product);
});
}
});
});
// Display recommendations
displayCartRecommendations(recommendedProducts);
}
})
.catch(error => console.error('Error fetching cart recommendations:', error));
}
function displayCartRecommendations(products) {
const container = document.getElementById('cart-recommendations');
if (!container) return;
container.innerHTML = `
<h3>You May Also Like</h3>
<div class="products-grid">
${products.map(product => `
<div class="product-card">
<img src="${product.images?.[0] || 'placeholder.jpg'}" alt="${product.name}">
<h4>${product.name}</h4>
<p class="price">$${product.prices?.[0]?.price || 'N/A'}</p>
<button onclick="addToCart('${product.refId}')">Add to Cart</button>
</div>
`).join('')}
</div>
`;
}
// Example usage
getCartRecommendations(['product123', 'product456']);
Personalized Homepage Recommendations
- Request
- Response
- JavaScript
GET https://<PA_END_POINT>/3.0/recommendations?currentUrl=https://www.example.com&customerId=customer123&expandProductDetails=true
{
"recommendations": {
"route": {
"id": "homepage-route-id",
"name": "Homepage Route",
"widgets": [
{
"id": "recently-viewed-widget-id",
"name": "Recently Viewed Products",
"slots": [
{
"label": "Recently Viewed Slot",
"tacticId": "recently-viewed-tactic",
"products": [
{
"refId": "product123",
"name": "Recently Viewed Product",
"description": "You viewed this product",
"isInStock": true,
"images": ["https://example.com/product123.jpg"],
"prices": [
{
"price": 79.99,
"code": "USD"
}
]
}
]
},
{
"label": "Recently Viewed Slot",
"tacticId": "recently-viewed-tactic",
"products": [
{
"refId": "product124",
"name": "Another Recently Viewed Product",
"description": "You viewed this product too",
"isInStock": true,
"images": ["https://example.com/product124.jpg"],
"prices": [
{
"price": 89.99,
"code": "USD"
}
]
}
]
}
]
},
{
"id": "personalized-recommendations-widget-id",
"name": "Recommended For You",
"slots": [
{
"label": "Personalized Recommendation Slot",
"tacticId": "personal-recommendation-tactic",
"products": [
{
"refId": "product789",
"name": "Recommended Product",
"description": "Based on your browsing history",
"isInStock": true,
"images": ["https://example.com/product789.jpg"],
"prices": [
{
"price": 49.99,
"code": "USD"
}
]
}
]
},
{
"label": "Personalized Recommendation Slot",
"tacticId": "personal-recommendation-tactic",
"products": [
{
"refId": "product790",
"name": "Another Recommended Product",
"description": "Another product based on your history",
"isInStock": true,
"images": ["https://example.com/product790.jpg"],
"prices": [
{
"price": 59.99,
"code": "USD"
}
]
}
]
}
]
}
]
}
}
}
// Get personalized recommendations for the homepage
function getPersonalizedRecommendations(customerId) {
// Build parameters
const params = new URLSearchParams({
currentUrl: window.location.href, // Use actual current URL
customerId: customerId,
expandProductDetails: 'true'
});
// Make API request
fetch(`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.recommendations?.route?.widgets) {
// Process by widget type
data.recommendations.route.widgets.forEach(widget => {
if (widget.name === "Recently Viewed Products") {
renderRecentlyViewedSection(widget);
} else if (widget.name === "Recommended For You") {
renderPersonalRecommendationsSection(widget);
}
// Handle other widget types as needed
});
}
})
.catch(error => console.error('Error fetching personalized recommendations:', error));
}
function renderRecentlyViewedSection(widget) {
// Render the Recently Viewed section
const container = document.getElementById('recently-viewed-container');
if (!container || !widget.slots || widget.slots.length === 0) return;
const products = [];
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
products.push(...slot.products);
}
});
if (products.length === 0) {
container.style.display = 'none';
return;
}
container.innerHTML = `
<h2>${widget.name}</h2>
<div class="product-slider">
${products.map(product => `
<div class="product-card">
<img src="${product.images?.[0] || 'placeholder.jpg'}" alt="${product.name}">
<h3>${product.name}</h3>
<p class="price">$${product.prices?.[0]?.price || 'N/A'}</p>
<button>View Product</button>
</div>
`).join('')}
</div>
`;
container.style.display = 'block';
}
function renderPersonalRecommendationsSection(widget) {
// Render the Personalized Recommendations section
const container = document.getElementById('personalized-recs-container');
if (!container || !widget.slots || widget.slots.length === 0) return;
const products = [];
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
products.push(...slot.products);
}
});
if (products.length === 0) {
container.style.display = 'none';
return;
}
container.innerHTML = `
<h2>${widget.name}</h2>
<div class="product-grid">
${products.map(product => `
<div class="product-card">
<img src="${product.images?.[0] || 'placeholder.jpg'}" alt="${product.name}">
<h3>${product.name}</h3>
<p class="description">${product.description || ''}</p>
<p class="price">$${product.prices?.[0]?.price || 'N/A'}</p>
<button>View Product</button>
</div>
`).join('')}
</div>
`;
container.style.display = 'block';
}
// Example usage
getPersonalizedRecommendations('customer123');
Category/Search Page with Filtering
- Request
- Response
- JavaScript
GET https://<PA_END_POINT>/3.0/recommendations?currentUrl=https://www.example.com/category/shoes&indexFilterValue=price:[50 TO 200] AND category:running&customerSegments[0]=premium_member&expandProductDetails=true
{
"recommendations": {
"route": {
"id": "category-route-id",
"name": "Category Page Route",
"widgets": [
{
"id": "popular-in-category-widget-id",
"name": "Popular in Running Shoes",
"slots": [
{
"label": "Popular Items Slot",
"tacticId": "popular-in-category-tactic",
"products": [
{
"refId": "shoe123",
"name": "Premium Running Shoe",
"description": "Top-rated running shoe",
"isInStock": true,
"images": ["https://example.com/shoe123.jpg"],
"prices": [
{
"price": 129.99,
"code": "USD"
}
]
}
]
},
{
"label": "Popular Items Slot",
"tacticId": "popular-in-category-tactic",
"products": [
{
"refId": "shoe124",
"name": "Another Running Shoe",
"description": "Another top-rated running shoe",
"isInStock": true,
"images": ["https://example.com/shoe124.jpg"],
"prices": [
{
"price": 139.99,
"code": "USD"
}
]
}
]
}
]
}
]
}
}
}
// Get filtered recommendations for a category page
function getCategoryRecommendations(categoryParams) {
// Build parameters
const params = new URLSearchParams();
// Use the actual current URL from the browser
params.append('currentUrl', window.location.href);
// Add filters
if (categoryParams.priceRange) {
params.append('indexFilterValue', `price:[${categoryParams.priceRange.min} TO ${categoryParams.priceRange.max}]`);
}
if (categoryParams.categoryFilter) {
// Append to existing filter if price range was added
const existingFilter = params.get('indexFilterValue');
const categoryFilter = `category:${categoryParams.categoryFilter}`;
if (existingFilter) {
params.set('indexFilterValue', `${existingFilter} AND ${categoryFilter}`);
} else {
params.append('indexFilterValue', categoryFilter);
}
}
// Add customer segments if available
if (categoryParams.customerSegments && categoryParams.customerSegments.length > 0) {
categoryParams.customerSegments.forEach((segment, index) => {
params.append(`customerSegments[${index}]`, segment);
});
}
params.append('expandProductDetails', 'true');
// Make API request
fetch(`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.recommendations?.route?.widgets) {
// Process and display the recommendations
const container = document.getElementById('category-recommendations');
if (!container) return;
let html = '';
data.recommendations.route.widgets.forEach(widget => {
html += `<h2>${widget.name}</h2>`;
html += '<div class="products-row">';
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
slot.products.forEach(product => {
html += `
<div class="product-card">
<img src="${product.images?.[0] || 'placeholder.jpg'}" alt="${product.name}">
<h3>${product.name}</h3>
<p class="description">${product.description || ''}</p>
<p class="price">$${product.prices?.[0]?.price || 'N/A'}</p>
<button onclick="addToCart('${product.refId}')">Add to Cart</button>
</div>
`;
});
}
});
html += '</div>';
});
container.innerHTML = html;
}
})
.catch(error => console.error('Error fetching category recommendations:', error));
}
// Example usage
getCategoryRecommendations({
priceRange: { min: 50, max: 200 },
categoryFilter: 'running',
customerSegments: ['premium_member']
});
Best Practices
Caching Recommendations
For better performance, consider caching recommendations where appropriate:
// Cache recommendations with appropriate TTL based on page type
function getCachedRecommendations(params, cacheKey, cacheDuration) {
// Check if we have a valid cached version
const cachedData = localStorage.getItem(cacheKey);
if (cachedData) {
const parsed = JSON.parse(cachedData);
// Check if the cache is still valid
if (parsed.timestamp && (Date.now() - parsed.timestamp < cacheDuration)) {
console.log(`Using cached recommendations for ${cacheKey}`);
return Promise.resolve(parsed.data);
}
}
// No valid cache, fetch from API
return fetch(`https://<PA_END_POINT>/3.0/recommendations?${params.toString()}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
// Cache the result
localStorage.setItem(cacheKey, JSON.stringify({
timestamp: Date.now(),
data: data
}));
return data;
});
}
// Example usage
function getProductPageRecommendations(productId) {
const params = new URLSearchParams({
currentUrl: window.location.href,
refId: productId,
expandProductDetails: 'true'
});
// Cache PDP recommendations for 5 minutes (300000 ms)
return getCachedRecommendations(params, `pdp_recommendations_${productId}`, 300000);
}
Progressive Loading
Implement progressive loading for better user experience:
// Load recommendations asynchronously as sections scroll into view
function setupLazyLoadedRecommendations() {
// Set up intersection observer to load recommendations when in view
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const element = entry.target;
const sectionType = element.dataset.recommendationType;
const params = element.dataset.params ? JSON.parse(element.dataset.params) : {};
// Show loading state
element.innerHTML = '<div class="loading-spinner"></div>';
// Load recommendations based on section type
if (sectionType === 'pdp') {
const productId = params.productId;
// Set up parameters
const apiParams = new URLSearchParams({
currentUrl: window.location.href,
refId: productId,
expandProductDetails: 'true'
});
// Fetch recommendations
fetch(`https://<PA_END_POINT>/3.0/recommendations?${apiParams.toString()}`, {
headers: {
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
renderRecommendationsToElement(element, data);
})
.catch(error => {
console.error('Error loading recommendations:', error);
element.innerHTML = '<p>Unable to load recommendations at this time.</p>';
});
}
// Once loaded, stop observing this element
observer.unobserve(element);
}
});
}, {
rootMargin: '100px 0px', // Load recommendations 100px before they come into view
threshold: 0.1
});
// Observe all recommendation containers
document.querySelectorAll('.recommendation-container[data-recommendation-type]').forEach(container => {
observer.observe(container);
});
}
function renderRecommendationsToElement(element, data) {
if (!data.recommendations?.route?.widgets || data.recommendations.route.widgets.length === 0) {
element.style.display = 'none';
return;
}
let html = '';
data.recommendations.route.widgets.forEach(widget => {
if (!widget.slots || widget.slots.length === 0) return;
html += `<h2>${widget.name}</h2>`;
html += '<div class="products-carousel">';
widget.slots.forEach(slot => {
if (slot.products && slot.products.length > 0) {
slot.products.forEach(product => {
html += `
<div class="product-card">
<img src="${product.images?.[0] || 'placeholder.jpg'}" alt="${product.name}" loading="lazy">
<h3>${product.name}</h3>
<p class="price">$${product.prices?.[0]?.price || 'N/A'}</p>
<button>View Product</button>
</div>
`;
});
}
});
html += '</div>';
});
element.innerHTML = html;
// Initialize carousel if needed
if (window.initProductCarousel) {
window.initProductCarousel(element.querySelector('.products-carousel'));
}
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', setupLazyLoadedRecommendations);
These examples demonstrate how to integrate the Recommendations API into various parts of your eCommerce website, from product detail pages to shopping carts and personalized homepages, along with best practices for performance optimization.