RecomNext

Widgets Guide

Use ready-to-ship recommendation carousels in both vanilla JavaScript and React. Install from npm (npm install @recomnext/carousel or npm install @recomnext/react-carousel). Installation constitutes acceptance of the SDK License Agreement. This guide covers initialization, parameters, rendering, and tracking.

@recomnext/carousel
@recomnext/react-carousel
@recomnext/live-search
@recomnext/global-search
@recomnext/live-search-react
@recomnext/global-search-react

Widget baseUrl for this environment
Engine API base URLAdmin UI
https://api.recomnext.comhttps://admin.recomnext.com

Use the engine base URL as baseUrl in widgets and SDKs.

Widget Types

Choose the widget package based on your frontend stack:

PackageUse CaseInitializationBest For
@recomnext/carouselVanilla JS / static pagesAuto-discovery + constructorLanding pages, CMS, no-framework apps
@recomnext/react-carouselReact appsReact component propsSPA product pages, custom card rendering
@recomnext/live-searchFull-page search + browsedata-recomnext-live-searchShop / PLP pages (v1 or v2)
@recomnext/global-searchHeader typeaheaddata-recomnext-global-searchSite header search dropdown
@recomnext/live-search-reactReact full-page searchRecomnextLiveSearch propsReact storefront PLP
@recomnext/global-search-reactReact header searchRecomnextGlobalSearch propsReact app nav bar
Search Widgets: LiveSearch & GlobalSearch

Search widgets support searchVersion="v1" or "v2". LiveSearch browses the catalog when the query is empty (public HMAC on GET /catalog/items).

<!-- Header typeahead -->
<div
  data-recomnext-global-search
  data-base-url="https://api.recomnext.com"
  data-tenant-id="YOUR_TENANT"
  data-public-token="rnx_pub_..."
  data-search-version="v2"
  data-shop-url="/search?q={query}"
></div>
<script src="/assets/recomnext-global-search.js"></script>

<!-- Full-page shop search -->
<div
  data-recomnext-live-search
  data-base-url="https://api.recomnext.com"
  data-tenant-id="YOUR_TENANT"
  data-public-token="rnx_pub_..."
  data-search-version="v2"
  data-sync-url="true"
></div>
<script src="/assets/recomnext-live-search.js"></script>
Vanilla Widget: Quick Start

The vanilla widget auto-initializes every element with data-recomnext-carousel on page load. You only need HTML data attributes and the widget script.

<div
  data-recomnext-carousel
  data-base-url="https://api.recomnext.com"
  data-tenant-id="demo-ecommerce"
  data-logic="similar-products"
  data-item-id="prod-001"
  data-scenario="pdp-similar"
  data-country="IN"
  data-count="8"
  data-return-properties="true"
  data-included-properties="attributes.name,attributes.price,attributes.image,category"
  data-title="You Might Also Like"
  data-item-url="/products/{itemId}"
></div>
<script src="/assets/recomnext-carousel.js"></script>
Vanilla Widget Parameters
NameRequiredTypeDetails
data-base-urlYesstringEngine API base URL (e.g. https://api.recomnext.com). See environment table above.
data-tenant-idYesstringTenant identifier sent in X-Tenant-Id header.
data-logicNouser-to-item | item-to-item | similar-products | recently-viewed | items-to-itemsRecommendation logic. Default is user-to-item.
data-item-idConditionalstringRequired for item-to-item and similar-products.
data-item-idsConditionalstringComma-separated item IDs for items-to-items.
data-user-idNostringYour user ID (account ID, customer ID, etc.). Falls back to auto-generated session ID when omitted.
data-scenarioNostringScenario slug to apply custom filters, boosters, and constraints.
data-countryNostringISO-3166-1 alpha-2 market (e.g. IN). Sent on recommend, impressions, and click views. Omit or OTH for global ranking.
data-countNonumberNumber of items to fetch. Default is 8.
data-return-propertiesNotrue | falseProjection toggle. Default true. false requests lean identity-only payload.
data-included-propertiesNocomma-separated stringExact raw item paths (for example attributes.name,attributes.image).
data-titleNostringSection heading shown above the carousel.
data-item-urlNostringCard URL template. Uses {itemId}. Default is /products/{itemId}.
data-public-tokenNostringPublic signing token for browser request signing when enabled.
User identity

The engine never assigns user IDs server-side. You control the identifier sent on recommendation, impression, and interaction calls.

IntegrationHow to pass your user ID
HTML widgetdata-user-id="your-user-id"
React widgetuserId="your-user-id" prop
Programmatic (vanilla)RecomnextCarousel(el, { userId: "your-user-id", ... })
Browser SDKuserId in constructor, or setUserId() after login
Direct APIuserId in URL path (/recommendations/user-to-item/:userId) or JSON body
Anonymous → logged-in flow
// 1) Anonymous: omit userId — widget uses sess_<timestamp>_<random> in sessionStorage
// 2) After login: pass your account ID and merge prior anonymous history (Browser SDK)
await recomnext.mergeIdentity(loggedInUserId);
recomnext.setUserId(loggedInUserId);
// 3) Re-render React widget with userId={loggedInUserId} (or update data-user-id)
Vanilla Widget: Programmatic Initialization

Use constructor-based initialization for dynamic pages, custom lifecycle handling, or SPA route transitions.

import { RecomnextCarousel } from '@recomnext/carousel';

const el = document.getElementById('recs');
const carousel = new RecomnextCarousel(el, {
  baseUrl: 'https://api.recomnext.com',
  tenantId: 'demo-ecommerce',
  logic: 'user-to-item',
  userId: 'user-123', // your stable ID — omit for anonymous session fallback
  count: 8,
  returnProperties: true,
  includedProperties: ['attributes.name', 'attributes.price', 'attributes.image', 'category'],
  title: 'Recommended For You',
  scenario: 'homepage-for-you',
});

// On route teardown:
carousel.destroy();
React Widget: Quick Start

In React apps, use the RecomnextCarousel component and pass logic-specific props.

import { RecomnextCarousel } from '@recomnext/react-carousel';

export function ProductRecommendations({ productId }: { productId: string }) {
  return (
    <RecomnextCarousel
      baseUrl="/api"
      tenantId="demo-ecommerce"
      logic="similar-products"
      itemId={productId}
      scenario="pdp-similar"
      country="IN"
      count={8}
      returnProperties={true}
      includedProperties={['attributes.name', 'attributes.price', 'attributes.image', 'category']}
      title="Similar Products"
      onItemClick={(item) => {
        window.location.href = '/products/' + item.itemId;
      }}
    />
  );
}
React Widget Props
NameRequiredTypeDetails
baseUrlYesstringEngine API base URL.
tenantIdYesstringTenant ID sent with each request.
logicYesLogicTypeRecommendation logic: user-to-item, item-to-item, similar-products, recently-viewed, or items-to-items.
itemIdConditionalstringRequired for item-to-item and similar-products.
itemIdsConditionalstring[]Required for items-to-items.
userIdNostringYour user ID. Auto session ID (sess_…) when omitted. Required for user-to-item and recently-viewed logic.
scenarioNostringScenario slug for recommendation configuration.
countryNostringISO-3166-1 alpha-2 market (e.g. IN). Sent on recommend, impressions, and click views. Omit or OTH for global ranking.
countNonumberNumber of items to request. Default is 8.
returnPropertiesNobooleanProjection toggle. Default true. false returns lean identity-only payload.
includedPropertiesNostring[]Exact raw item paths to include (for example attributes.name).
titleNostringWidget title shown above cards.
classNameNostringContainer class for custom styling.
styleNoCSSPropertiesInline style object for container.
renderItemNo(item, index) => ReactNodeCustom card renderer.
onItemClickNo(item) => voidCallback fired when a card is clicked.
onImpressionNo(items) => voidCallback fired for newly visible cards.
publicTokenNostringPublic signing token for browser request signing when enabled.
Strict-HMAC Projection Contract

Projection placement must match request signing scope exactly.

GET (user-to-item, item-to-item, similar-products, recently-viewed):
- returnProperties + includedProperties go in query and are included in the signed URL.

POST (items-to-items):
- returnProperties + includedProperties go in JSON body only.
- Query stays scenario/user context only.

If placement and signature scope differ, the engine rejects the request.
Customization Examples
Custom React Card Renderer
<RecomnextCarousel
  baseUrl="/api"
  tenantId="demo-ecommerce"
  logic="user-to-item"
  count={10}
  title="Top Picks"
  renderItem={(item) => (
    <a
      href={'/products/' + item.itemId}
      style={{
        display: 'block',
        width: 220,
        borderRadius: 12,
        border: '1px solid #eee',
        textDecoration: 'none',
        color: '#111',
        overflow: 'hidden',
      }}
    >
      {item.image && <img src={item.image} alt={item.name} style={{ width: '100%', aspectRatio: '1', objectFit: 'cover' }} />}
      <div style={{ padding: 12 }}>
        <p style={{ margin: 0, fontWeight: 600 }}>{item.name}</p>
        <p style={{ margin: '4px 0 0', color: '#666', fontSize: 12 }}>{item.category}</p>
      </div>
    </a>
  )}
/>
Vanilla Widget with Multiple Carousels
<div
  data-recomnext-carousel
  data-base-url="https://api.recomnext.com"
  data-tenant-id="demo-ecommerce"
  data-logic="user-to-item"
  data-user-id="user-123"
  data-scenario="homepage-for-you"
  data-title="For You"
></div>

<div
  data-recomnext-carousel
  data-base-url="https://api.recomnext.com"
  data-tenant-id="demo-ecommerce"
  data-logic="recently-viewed"
  data-user-id="user-123"
  data-title="Recently Viewed"
></div>
How Rendering Works
  • Widget injects scoped carousel styles once and renders a loading skeleton immediately.
  • Recommendations are fetched using the selected logic and optional scenario.
  • Response items are mapped into card data fields: itemId, name, category, price, image, url.
  • Lean/projection payloads are supported; widgets tolerate missing attributes, image, category, and price without throwing.
  • Cards render in a horizontal track with snap scrolling for touch and desktop trackpads.
  • If no items are returned, the widget renders an empty state message.
  • Each card includes data-item-id for analytics tracking and custom hooks.
Projection Behavior Guide
ModeRecommended UsageWidget Output
Default full payloadLeave projection props unsetFull cards with name/image/category/price when catalog data has them
Selective projectionSet returnProperties=true with includedProperties pathsCards render only requested fields plus identity
Lean modeSet returnProperties=false intentionallyMinimal identity-driven cards; missing metadata is rendered safely
Tracking and Analytics

Widgets track both click interactions and impressions automatically.

SignalTriggerEndpointPayload Highlights
Card clickUser clicks/taps a card/ingestion/interactionsuserId, itemId, type=view, scenarioSlug (from data-scenario), timestamp
Site-wide eventPDP view / cart / purchase outside carousel/ingestion/interactionsuserId, itemId, type — scenarioSlug omitted
ImpressionCard reaches >= 50% visibility/ingestion/impressionsuserId, itemIds[], scenarioSlug, timestamp
Logic Selection Guide
Logic TypeInput NeededTypical Placement
user-to-itemuserId (or session)Home feed, account dashboard
item-to-itemitemIdProduct detail page: related products
similar-productsitemIdProduct detail page: semantic similarity
recently-vieweduserId (or session)Home page continuation, cart page
items-to-itemsitemIds[]Cart page cross-sell or checkout upsell
Troubleshooting
  • No cards rendered: verify baseUrl, tenantId, and logic-specific inputs (itemId or itemIds).
  • Empty recommendations: ensure catalog and interactions are ingested and the selected scenario is valid. If the scenario filter is strict, opt-in autoRelaxFilters (durable clauses left, soft right) — see Query planning for filter auto-relax. Widgets inherit scenario flags; no new widget attributes.
  • Only ID links show (no name/image/price): check if returnProperties=false is enabled or if includedProperties paths do not match raw item paths from /catalog/items.
  • HTTP 400 on recommendations: verify includedProperties has no unsafe segments (for example __proto__, constructor) and stays within GET path/length limits.
  • Broken links: check data-item-url or custom click navigation handlers.
  • No impression events: confirm cards are in viewport and browser supports IntersectionObserver.
  • 401/403 errors: verify tenant auth setup and pass publicToken when browser signing is required.

Next Steps

After adding widgets, continue with:

  • Integration Guides — run the local stack and seed test data.
  • nextQL Guide — build filter and booster expressions for scenarios.
  • API Reference — inspect recommendation and ingestion endpoint contracts.
  • SDK Docs — integrate typed Browser and Node clients.
RecomNext | Recommendation as a Service