Implementing Blog Carousel Personalization using Sitecore Personalize and Decision Models

 Personalization becomes significantly more powerful when it is driven by real user behavior. Instead of showing static content to every visitor, we can dynamically adapt experiences based on how users interact with the website.

In this blog, I will walk through a real implementation where we personalized a Blog Carousel on the homepage using Sitecore Personalize and Decision Models.

The goal was simple:

When a returning visitor lands on the homepage, the blog carousel should prioritize the last blog article viewed in their previous session.

This ensures users immediately see content that is most relevant to them.


Solution Architecture

The implementation involved three main components:

  1. Custom Event Tracking in Next.js

  2. Decision Model in Sitecore Personalize

  3. Personalized Experience with Web Template

The overall flow looks like this:

User Reads Blog Article

Custom Event Sent from Next.js

Event Stored in Sitecore CDP

Decision Model Evaluates Visitor History

Returns Last Viewed Blog

Homepage Blog Carousel Reordered


Step 1 – Tracking Blog Article Views in Next.js

To capture blog interactions, we created a custom event that fires whenever a user visits a blog article page.

This event stores article information in CDP so that it can later be used for personalization.

Example Next.js Event Implementation

import { sendEvent } from "@sitecore/engage";

export const trackBlogView = (article) => {

const eventData = {
channel: "WEB",
type: "BLOG_ARTICLE_VIEW",
language: "EN",
currency: "USD",
page: article.title,
pos: "website",

arbitraryData: {
articleId: article.id,
articleTitle: article.title,
articleCategory: article.category,
articleUrl: article.url,
viewedAt: new Date().toISOString()
}
};

sendEvent(eventData);
};

This event captures:

  • Article ID

  • Article title

  • Category

  • URL

  • Timestamp

This data is stored inside Sitecore CDP as part of the visitor's event history.


Step 2 – Decision Model to Retrieve Last Viewed Blog

Next, we created a Decision Model that evaluates visitor behavior and returns the most recently viewed blog article.

The model scans visitor event history and identifies the latest blog view event.

Decision Model Script

(function () {

if (!guest || !guest.sessions) {
return null;
}

var lastViewedArticle = null;
var lastTimestamp = null;

for (var i = 0; i < guest.sessions.length; i++) {

var session = guest.sessions[i];

if (!session.events) continue;

for (var j = 0; j < session.events.length; j++) {

var event = session.events[j];

if (event.type === "BLOG_ARTICLE_VIEW") {

var eventTime = new Date(event.createdAt);

if (!lastTimestamp || eventTime > lastTimestamp) {

lastTimestamp = eventTime;

lastViewedArticle = {
id: event.arbitraryData.articleId,
title: event.arbitraryData.articleTitle,
url: event.arbitraryData.articleUrl
};

}
}
}
}

return lastViewedArticle;

})();

This logic:

  1. Iterates through visitor sessions

  2. Identifies all BLOG_ARTICLE_VIEW events

  3. Finds the most recent event

  4. Returns article details

The output of the decision model is used by the experience to update the carousel.


Step 3 – Personalize Experience (Updating Blog Carousel)

Once the decision model returns the last viewed article, we update the homepage carousel dynamically.

We implemented this using a Web Template in Sitecore Personalize.

Example Web Template Script

(function () {

function personalizeCarousel() {

if (!variant || !variant.article) {
return;
}

const articleId = variant.article.id;

const carousel = document.querySelector("#blog-carousel");

if (!carousel) return;

const articleElement = carousel.querySelector(`[data-article-id="${articleId}"]`);

if (articleElement) {

carousel.prepend(articleElement);

}

}

personalizeCarousel();

})();

What this script does:

  1. Reads the article returned by the decision model.

  2. Locates the corresponding blog card in the carousel.

  3. Moves it to the first position.

As a result, the blog carousel dynamically prioritizes the last viewed article.


Why We Used a Decision Model Instead of Conditions

Conditions in Sitecore Personalize are useful for simple targeting such as:

  • Logged-in users

  • Device type

  • Location

However, in this scenario we needed to:

  • Evaluate visitor behavior

  • Process event history

  • Return dynamic content

This makes Decision Models the ideal choice, as they act as a decision engine that processes behavioral data and returns relevant content.


Final Result

Before Personalization:

Blog carousel shows the same order for all users.

After Personalization:

Returning visitors see their last viewed blog article prioritized at the top.

Example:

Default Carousel

  1. Heart Health Tips

  2. Nutrition Guide

  3. Fitness Routine

Returning Visitor Who Previously Read "Nutrition Guide"

  1. Nutrition Guide

  2. Heart Health Tips

  3. Fitness Routine

This small change significantly improves user engagement.


Key Benefits

This implementation delivers several advantages:

Improved Engagement
Users are more likely to interact with content relevant to their interests.

Behavior-driven Personalization
Content adapts dynamically based on visitor history.

Reusable Decision Logic
The same decision model can power multiple personalization use cases.

Scalable Architecture
The logic is separated from the experience layer, making it easier to maintain and extend.


Final Thoughts

Personalization works best when it is driven by real user behavior. By combining custom events, decision models, and personalized experiences, Sitecore Personalize enables organizations to deliver dynamic, context-aware content.

Even a simple enhancement like prioritizing the last viewed blog article can significantly improve content discovery and user engagement.


✍️ Author
Mahesh Kambhampati
Sitecore Developer | XM Cloud | CDP | Personalize

Comments

Popular posts from this blog

No More Delays: How to Instantly Reflect Sitecore XM Cloud Changes on Netlify & Vercel

Optimizing Layout Service: Exposing Sitecore Search Configurations for Each Page in XM Cloud