How to Add Personalization to Slick Carousel in Adobe Experience Manager (AEM)
Leo Ruiz, May 4, 2021
Intro
Having to personalize the carousel component is a common request from clients, and typically it needs to support personalisation. This should be a simple request, but without understanding the intricacies of DOM triggers, you'll quickly get frustrated by errors when trying to preview the component. Read on, as we uncover the core issue and demonstrate how to solve it.
Aw, Snap!
Throughout my extensive experience as a Front-End Developer, I've found myself on more than one occasion having to create an AEM component that contains a carousel, that should also supports personalization. It seems like a rather simple task on the surface - but there is one big problem. After personalizing the carousel component, clicking ‘View as Published’ would immediately collapse the entire site and throw up an ‘aw snap’ error. Not great!
Root Cause
It took a few days of debugging I found the root of the problem:
When the personalization starts its process, it renders the component with the default data (i.e. it loads the component without the personalization). After this default component is rendered, the DOM triggers the document.ready
event and with this event my JS begins its execution. The JS file then tries to add the carousel by doing $component.slick({params}); - but at this exact moment, the personalization process starts the second render of the component (this time with the personalized data).
Unfortunately, the slick process doesn't get the memo; it will try to finish the carousel creation on a DOM element which no longer exists. As a result, the slick tries over and over again to create the carousel, creating a stack overflow in the browser... and thus, displays the ‘aw, snap’ error mentioned before.
Fixing It
Now that we know how the problem is caused - how do we fix it?
The simple answer is:
$(element).parent().parent().hasClass('campaign');
This code checks if the grandparent of the element contains the class ‘campaign’, this is how AEM notices if the component is being personalized.
The second (and slightly more difficult) piece to solving the 'aw snap' error is to add:
ContextHub.eventing.on(
ContextHub.Constants.EVENT_TEASER_LOADED, function (event, teaser) {
teaser.data.forEach(function (data) {
const element = $('#'+data.key).children().children();
if (element.hasClass('component-class')) {
initCarousel(element);
}
});
}
);
Take Note
Note that we have to control the ContextHub eventing. It’s vital that we make this with the ‘.on’ method, because if we use ‘.once’ it will only be executed one time, thus causing bad functionality if we have 2 or more personalized components in the same page.
The function ContextHub.eventing.on receives 2 parameters. The first one is the constant EVENT_TEASER_LOADED, which indicates the event we are listening to, and the second one is a function. This anonymous function receives two parameters. The most important parameter is the second one - the ‘teaser’ param. This parameter will receive all the data related to which component triggered the event, so we can check if our component has to be initialized or not. This is an array, as 2 or more elements could trigger the same event at the same time. We review each element and check if the grandchild of that element is our component. In this case, I can check it through the class name, if this is a true statement, then we can initialize that component.
That's a Wrap!
I hope you found this blog post useful! Should you have further questions, please don't hesitate to reach out to us here and reference this blog post.
Topics: Adobe Experience Manager, Digital Marketing, AEM, Personalization, ContextHub