In this post I will share my experience working with Coveo content recommendation, in a recent project we wanted to implemented content recommendation for blogs items, while we utilized the wildcard approach for blog details page, this was challenging, specially with Coveo analytics and view event, keep reading to know more!!
While working on implementing content recommendation with Coveo, we added all needed pieces, starting from the Hive components on the presentation details for the blog details page, up to the Coveo query pipeline and the content recommendation machine learning model on Coveo cloud, we start seeing information and data collected, and just waited the model to learn and start providing recommendations.
But for some reason, regardless of how long we waited or how much data were collected, we didn't get any recommendations back, the different thing about our setup, was that our detail page was configured using wild card. so the fist issue was the Id being passed to the Coveo Analytics view event is always the same which was essential for the Coveo model to learn, after investigating we found that the event JS code is in Areas\CoveoHiveSxa\Views\Analytics\Coveo Page View Analytics.cshtml see the following:
@using Coveo.UI.Components
@using Coveo.UI.Components.Extensions
@using Coveo.UI.Components.Sxa.Extensions
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@model Coveo.UI.Components.Sxa.Areas.CoveoHiveSxa.Models.Analytics.PageViewAnalyticsModel
<div @Html.Sxa().Component("coveo-pageviewanalytics", Model.Attributes)>
@Html.Coveo().RenderErrorSummary(Model.ValidateModel())
@if (Model.IsConfigured) {
@Html.Partial(Partials.EDIT_TITLE, "Coveo Usage Analytics Page View")
if (Model.Properties.AnalyticsEnabled) {
<script>
// Code snippet to load and log page view analytics.
// Imported from https://github.com/coveo/coveo.analytics.js
(function (c, o, v, e, O, u, a) {
a = 'coveoua'; c[a] = c[a] || function () { (c[a].q = c[a].q || []).push(arguments) };
c[a].t = Date.now(); u = o.createElement(v); u.async = 1; u.src = e;
O = o.getElementsByTagName(v)[0]; O.parentNode.insertBefore(u, O)
})(window, document, 'script', 'https://static.cloud.coveo.com/coveo.analytics.js/2/coveoua.js');
document.addEventListener("CoveoSearchEndpointInitialized", function () {
var accessToken = Coveo && Coveo.SearchEndpoint && Coveo.SearchEndpoint.defaultEndpoint && Coveo.SearchEndpoint.defaultEndpoint.accessToken
? Coveo.SearchEndpoint.defaultEndpoint.accessToken.token
: "";
var customMetadata = @Html.Raw(Model.Properties.MetadataAsJson);
if (typeof (CoveoForSitecoreUserContext) !== "undefined") {
var currentContext = CoveoForSitecoreUserContext.handler.getContext();
Object.keys(currentContext).forEach(function(key) {
customMetadata["c_context_" + key] = currentContext[key];
});
}
coveoua('onLoad', function() {
Object.defineProperty(coveoanalytics.CoveoAnalyticsClient.prototype, 'baseUrl', { get() { return "@Model.Properties.CoveoAnalyticsEndpoint" + "/v15" }});
coveoua('init', accessToken);
coveoua('send', 'view', customMetadata);
});
});
</script>
}
}
</div>
To workaround the issue, we needed to dynamically get the Id of the current blog data item and inject it into the view event, here is how we did:
@using Coveo.UI.Components
@using Coveo.UI.Components.Extensions
@using Coveo.UI.Components.Sxa.Extensions
@using Sitecore.XA.Foundation.MarkupDecorator.Extensions
@using Sitecore.XA.Foundation.SitecoreExtensions.Extensions
@model Coveo.UI.Components.Sxa.Areas.CoveoHiveSxa.Models.Analytics.PageViewAnalyticsModel
<div @Html.Sxa().Component("coveo-pageviewanalytics", Model.Attributes)>
@Html.Coveo().RenderErrorSummary(Model.ValidateModel())
@if (Model.IsConfigured)
{
@Html.Partial(Partials.EDIT_TITLE, "Coveo Usage Analytics Page View")
if (Model.Properties.AnalyticsEnabled)
{
<script>
// Code snippet to load and log page view analytics.
// Imported from https://github.com/coveo/coveo.analytics.js
(function (c, o, v, e, O, u, a) {
a = 'coveoua'; c[a] = c[a] || function () { (c[a].q = c[a].q || []).push(arguments) };
c[a].t = Date.now(); u = o.createElement(v); u.async = 1; u.src = e;
O = o.getElementsByTagName(v)[0]; O.parentNode.insertBefore(u, O)
})(window, document, 'script', 'https://static.cloud.coveo.com/coveo.analytics.js/2/coveoua.js');
document.addEventListener("CoveoSearchEndpointInitialized", function () {
var accessToken = Coveo && Coveo.SearchEndpoint && Coveo.SearchEndpoint.defaultEndpoint && Coveo.SearchEndpoint.defaultEndpoint.accessToken
? Coveo.SearchEndpoint.defaultEndpoint.accessToken.token
: "";
var customMetadata = @Html.Raw(Model.Properties.MetadataAsJson);
// workaround blog wildcard issue
var datasourceElement = document.getElementById('datasourceid');
if (datasourceElement != undefined) {
var blogId = datasourceElement.getAttribute("data-blogId");
if (blogId != '' && blogId != undefined) {
customMetadata["contentIdValue"] = blogId.replace(/[{}-]/g, '');
}
}
// end of workaround.
if (typeof (CoveoForSitecoreUserContext) !== "undefined") {
var currentContext = CoveoForSitecoreUserContext.handler.getContext();
Object.keys(currentContext).forEach(function(key) {
customMetadata["c_context_" + key] = currentContext[key];
});
}
coveoua('onLoad', function() {
Object.defineProperty(coveoanalytics.CoveoAnalyticsClient.prototype, 'baseUrl', { get() { return "@Model.Properties.CoveoAnalyticsEndpoint" + "/v15" }});
coveoua('init', accessToken);
coveoua('send', 'view', customMetadata);
});
});
</script>
}
}
</div>
Notice that the guid must be with specific format, not the full one, once we have that completed, we waited a little for the model to learn and it started to recommend content based on users analytics. hopefully someone will find this useful.
No comments:
Post a Comment