Documentation Index Fetch the complete documentation index at: https://docs.joinrefine.io/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Visitor recommendations personalize the shopping experience for anonymous users based on their current session behavior. No login required — Refine tracks visitors using automatically generated IDs stored in localStorage.
Basic Usage
import { Refine } from '@refine-ai/sdk' ;
const refine = new Refine ({
apiKey: process . env . REFINE_API_KEY ,
organizationId: 'org_abc123' ,
catalogId: 'cat_xyz789'
});
const recs = await refine . recs . forVisitor ({
configId: 'homepage_personalized' ,
topK: 12
});
recs . results . forEach ( product => {
console . log ( ` ${ product . title } - $ ${ product . price } ` );
});
Parameters
Recommendation configuration ID from the dashboard. Defines the algorithm and business rules.
Number of recommendations to return. Recommended: 8-24.
Additional filters to apply. See Filters .
How Visitor Tracking Works
The SDK automatically manages visitor identity:
First Visit : A unique visitorId is generated and stored in localStorage
Subsequent Visits : The same visitorId is reused
Behavior Tracking : Product views, clicks, and searches are associated with the visitor
Recommendations : The algorithm uses this history to personalize results
// Check the current visitor ID
const visitorId = refine . getVisitorId ();
console . log ( 'Visitor:' , visitorId ); // e.g., "v_a1b2c3d4e5"
Visitor IDs persist across sessions but not across devices or browsers. Use User Recommendations for cross-device personalization.
Creating Configurations
Visitor recommendation configurations are created in the dashboard:
Dashboard → Recommendations → Configurations → New Configuration
Configuration options include:
Setting Description Strategy Collaborative filtering, content-based, or hybrid Fallback What to show for new visitors with no history Diversity How much to vary recommended categories Recency Bias Weight recent behavior more heavily Filters Default filters (e.g., in-stock only)
Tracking Visitor Recommendations
const recs = await refine . recs . forVisitor ({
configId: 'homepage_recs' ,
topK: 12
});
const recsContext = refine . events . trackRecommendations (
recs . serveId ,
recs . results ,
'home_page' ,
'visitor-recs'
);
// Track interactions
recsContext . trackClick ( productId , position );
recsContext . trackView ( productId , position );
recsContext . trackAddToCart ( productId );
With Filters
Apply runtime filters on top of configuration defaults:
const recs = await refine . recs . forVisitor ({
configId: 'homepage_recs' ,
topK: 12 ,
filters: [
{ field: 'price' , operator: 'lte' , value: 100 },
{ field: 'metadata.category' , operator: 'in' , value: [ 'womens' , 'accessories' ] }
]
});
Use Cases
Homepage Hero
Show personalized picks based on browsing history:
async function loadHomepageRecs () {
const recs = await refine . recs . forVisitor ({
configId: 'homepage_hero' ,
topK: 8
});
return recs . results ;
}
Category Page Enhancement
Mix algorithmic recommendations with category products:
async function loadCategoryPageRecs ( category : string ) {
const recs = await refine . recs . forVisitor ({
configId: 'category_page_recs' ,
topK: 8 ,
filters: [
{ field: 'metadata.category' , operator: 'eq' , value: category }
]
});
return recs . results ;
}
Search Fallback
When search returns no results, show personalized alternatives:
async function handleEmptySearch ( query : string ) {
const recs = await refine . recs . forVisitor ({
configId: 'search_fallback' ,
topK: 12
});
return {
message: `No results for " ${ query } ". You might like these:` ,
products: recs . results
};
}
Exit Intent
Show personalized recommendations in exit-intent popups:
document . addEventListener ( 'mouseleave' , async ( e ) => {
if ( e . clientY < 0 ) { // Mouse leaving viewport at top
const recs = await refine . recs . forVisitor ({
configId: 'exit_intent' ,
topK: 4
});
showExitPopup ( recs . results );
}
});
Complete Implementation
import { Refine } from '@refine-ai/sdk' ;
const refine = new Refine ({
apiKey: process . env . REFINE_API_KEY ,
organizationId: 'org_abc123' ,
catalogId: 'cat_xyz789'
});
class HomepageRecommendations {
private container : HTMLElement ;
private recsContext : any ;
constructor ( containerId : string ) {
this . container = document . getElementById ( containerId ) ! ;
this . load ();
}
private async load () {
this . container . innerHTML = '<p>Loading recommendations...</p>' ;
try {
const recs = await refine . recs . forVisitor ({
configId: 'homepage_personalized' ,
topK: 12
});
this . recsContext = refine . events . trackRecommendations (
recs . serveId ,
recs . results ,
'home_page' ,
'visitor-recs'
);
this . render ( recs . results );
this . setupViewabilityTracking ();
} catch ( error ) {
this . container . innerHTML = '<p>Unable to load recommendations.</p>' ;
console . error ( 'Recommendations error:' , error );
}
}
private render ( products : any []) {
this . container . innerHTML = `
<h2>Recommended for You</h2>
<div class="product-grid">
${ products . map (( product , index ) => `
<div class="product-card"
data-id=" ${ product . productId } "
data-position=" ${ index } ">
<img src=" ${ product . imageUrl } " alt=" ${ product . title } " />
<h3> ${ product . title } </h3>
<p class="price">$ ${ product . price . toFixed ( 2 ) } </p>
<button class="add-to-cart">Add to Cart</button>
</div>
` ). join ( '' ) }
</div>
` ;
// Click handlers
this . container . querySelectorAll ( '.product-card' ). forEach ( card => {
const productId = ( card as HTMLElement ). dataset . id ! ;
const position = parseInt (( card as HTMLElement ). dataset . position ! );
card . addEventListener ( 'click' , ( e ) => {
if (( e . target as HTMLElement ). classList . contains ( 'add-to-cart' )) {
this . recsContext ?. trackAddToCart ( productId );
} else {
this . recsContext ?. trackClick ( productId , position );
window . location . href = `/products/ ${ productId } ` ;
}
});
});
}
private setupViewabilityTracking () {
const observer = new IntersectionObserver (( entries ) => {
entries . forEach ( entry => {
if ( entry . isIntersecting ) {
const card = entry . target as HTMLElement ;
const productId = card . dataset . id ! ;
const position = parseInt ( card . dataset . position ! );
this . recsContext ?. trackView ( productId , position );
observer . unobserve ( card );
}
});
}, { threshold: 0.5 });
this . container . querySelectorAll ( '.product-card' ). forEach ( card => {
observer . observe ( card );
});
}
}
// Initialize
new HomepageRecommendations ( 'homepage-recs' );
New Visitor Handling
For first-time visitors with no history, the configuration’s fallback strategy kicks in:
Popular Items : Show best-sellers
New Arrivals : Show recently added products
Editorial Picks : Show curated selections
Configure fallback behavior in the dashboard.
Next Steps
User Recommendations Personalization for logged-in users
Similar Items Product-based recommendations