Skip to main content

Overview

Refine provides three types of recommendations, each optimized for different use cases:
TypeBest ForData Required
Similar ItemsProduct pages, “You may also like”Anchor product ID
Visitor RecommendationsHomepage, anonymous usersBrowsing history (automatic)
User RecommendationsLogged-in users, personalizationUser identification

Quick Start

import { Refine } from '@refine-ai/sdk';

const refine = new Refine({
  apiKey: process.env.REFINE_API_KEY,
  organizationId: 'org_abc123',
  catalogId: 'cat_xyz789'
});

// Similar items (product page)
const similar = await refine.recs.similarItems({
  anchorId: 'sku_dress_001',
  topK: 8
});

// Visitor recommendations (homepage, anonymous)
const forVisitor = await refine.recs.forVisitor({
  configId: 'homepage_recs',
  topK: 12
});

// User recommendations (logged-in users)
refine.identify('user_12345');
const forUser = await refine.recs.forUser({
  configId: 'personalized_picks',
  topK: 12
});

Configuration IDs

Visitor and user recommendations require a configId that references a recommendation configuration created in the Refine dashboard. Configurations define:
  • Strategy — Collaborative filtering, content-based, hybrid
  • Weighting — Balance between visual similarity and behavioral signals
  • Filters — Default filters applied to all recommendations
  • Business rules — Category diversity, price range constraints
Create configurations at: Dashboard → Recommendations → Configurations
Similar items don’t require a configId — they work directly with any product in your catalog.

Tracking Recommendations

Always track when recommendations are served to enable analytics and feedback loops:
const recs = await refine.recs.similarItems({
  anchorId: 'sku_001',
  topK: 8
});

const recsContext = refine.events.trackRecommendations(
  recs.serveId,
  recs.results,
  'product_page',   // surface
  'similar-items',  // source
  { anchorId: 'sku_001' }
);

// Track user interactions
recsContext.trackClick(productId, position);
recsContext.trackView(productId, position);
recsContext.trackAddToCart(productId);

Response Structure

All recommendation methods return the same structure:
interface RecommendationResponse {
  results: RecommendationItem[];
  serveId: string;
  totalResults: number;
}

interface RecommendationItem {
  productId: string;
  title: string;
  price: number;
  imageUrl: string;
  metadata: Record<string, any>;
  score: number;
}
results
RecommendationItem[]
Array of recommended products, ordered by relevance/score.
serveId
string
Unique identifier for this recommendation serve. Used for event tracking.
totalResults
number
Total number of available recommendations before topK limit.

Filtering Recommendations

Apply filters to narrow recommendations:
const recs = await refine.recs.similarItems({
  anchorId: 'sku_dress_001',
  topK: 8,
  filters: [
    { field: 'price', operator: 'lte', value: 150 },
    { field: 'stock', operator: 'gt', value: 0 },
    { field: 'metadata.category', operator: 'eq', value: 'dresses' }
  ]
});
See Filters for all available operators.

Visual Weight

For similar items, control the balance between visual similarity and other signals:
const recs = await refine.recs.similarItems({
  anchorId: 'sku_001',
  topK: 8,
  visualWeight: 0.7  // High visual similarity emphasis
});
visualWeightBehavior
0.0Pure metadata/behavioral matching
0.5Balanced (default for most)
1.0Pure visual similarity

Recommendation Strategies by Page

PageRecommended TypeConfiguration
Product Detail PageSimilar ItemsanchorId = current product
Homepage (anonymous)Visitor RecsPopular/trending config
Homepage (logged-in)User RecsPersonalized config
Cart PageSimilar ItemsMultiple anchors from cart
Category PageVisitor RecsCategory-specific config
Search (no results)Visitor RecsFallback/popular config

Error Handling

import { 
  RefineNotFoundError,
  RefineValidationError 
} from '@refine-ai/sdk';

try {
  const recs = await refine.recs.similarItems({
    anchorId: 'invalid_sku',
    topK: 8
  });
} catch (error) {
  if (error instanceof RefineNotFoundError) {
    // Anchor product doesn't exist
    console.log('Product not found, showing popular items instead');
    return await refine.recs.forVisitor({ configId: 'popular', topK: 8 });
  }
  if (error instanceof RefineValidationError) {
    console.error('Invalid parameters:', error.message);
  }
}

Next Steps