"Customers who bought this also bought…" sounds like a trivial widget until you're the one building it. Real recommendation logic — behavioral data, real-time personalization, A/B testing, fallback states — is not something you want to hand-roll. That's the gap Nosto fills, and this guide covers what actually goes into wiring it up.
What Nosto Is Doing Under the Hood
Nosto is a commerce personalization platform. You feed it a product catalog and behavioral events (views, cart adds, purchases), and it returns recommendation slots — "Bestsellers," "Recently Viewed," "Customers Also Bought" — tailored per visitor. The integration has two halves: getting data into Nosto, and rendering recommendations from Nosto on your storefront.
💡 Pro tip: Recommendations are only as good as the event data feeding them. A broken tracking snippet silently degrades personalization quality — it won't throw errors, it'll just quietly serve generic bestseller lists to everyone.
Installing the Tracking Script
Every page needs Nosto's base tracking snippet loaded before other scripts:
<script type="text/javascript" src="https://connect.nosto.com/embed/shopify/YOUR_ACCOUNT_ID"></script>
For non-Shopify stacks, use the platform-agnostic JS API instead:
window.nostojs(api => {
api.defaultSession()
.viewPage('/products/blue-running-shoes')
.load();
});
defaultSession() starts (or resumes) a visitor session; .load() sends the event and triggers Nosto to compute updated recommendations.
Sending Product and Category Events
Nosto's personalization engine runs on event signals. The three you'll implement first:
// Product page view
api.defaultSession()
.viewProduct('SKU12345')
.load();
// Category / listing page view
api.defaultSession()
.viewCategory('/collections/running-shoes')
.load();
// Add to cart
api.defaultSession()
.addSkuToCart('SKU12345', 1)
.load();
Each call updates the visitor's session profile, which is what Nosto uses to personalize the next set of recommendations it returns.
Rendering a Recommendation Slot
Recommendation placements are just divs with a designated id, mapped to a slot you configure in the Nosto admin:
<div class="nosto_element" id="frontpage-nosto-1"></div>
Nosto's script scans the page for these elements and injects the recommendation markup — product cards, images, prices — automatically. You control the layout of those cards via a template editor in the Nosto admin, not in your own codebase.
api.defaultSession()
.setPlacements(['frontpage-nosto-1'])
.load();
If you're building a custom storefront (headless commerce, React/Vue frontends), you can skip the DOM-injection model entirely and fetch recommendation data as JSON:
api.recommendation('frontpage-nosto-1')
.then(response => {
renderCustomCarousel(response.products);
});
Handling the Empty State
New visitors with no session history, or products with thin behavioral data, won't have personalized recommendations to serve. Always configure a fallback:
- Bestsellers or trending items as a catalog-wide default
- A minimum data threshold in the Nosto admin before a slot activates
- A loading skeleton rather than an empty div, since recommendation data loads asynchronously after initial page render
Testing Without Polluting Production Data
Nosto weights its models on real traffic, so testing against your live account can skew recommendations for real shoppers. Two practical guardrails:
- Use a separate staging account ID for development, not the production one
- If you must test on production, use Nosto's preview/test mode headers so test sessions are excluded from the personalization model
Where This Gets Non-Trivial
The basic setup above gets recommendations on the page. The parts that take real engineering time:
- Data feed accuracy — Nosto ingests your product catalog on a schedule; stale pricing or inventory in the feed shows up directly in recommendation cards
-
SPA navigation — single-page apps don't trigger full page loads, so you need to manually call
.load()on route changes or Nosto's session state goes stale - Multi-currency / multi-store — each storefront variant typically needs its own Nosto account or careful session scoping
Have you integrated Nosto (or a similar personalization engine) into a headless storefront? What was the trickiest part — the event tracking or the rendering layer? Drop your experience in the comments. 👇
#ecommerce #javascript #webdev #tutorial
Top comments (0)