Background
After cruising around the web looking for some code to use to trigger a goal using jQuery AJAX, I discovered that there weren't really any easy to understand, end-to-end, current examples of how to do this using Sitecore MVC.So, I decided to write up a quick post to demonstrate how to do this in 3 easy steps.
Step 1 - Create MVC Controller
The first step is to create an MVC Controller with an action that you will use to trigger the goal: using System;
using System.Linq;
using System.Web.Mvc;
using Sitecore.Analytics;
using Sitecore.Analytics.Data.Items;
using Sitecore.Mvc.Controllers;
namespace MyNamespace.Controllers
{
public class AnalyticsController : SitecoreController
{
private const string DefaultGoalLocation = "/sitecore/system/Marketing Control Panel/Goals";
[HttpPost]
public ActionResult TriggerGoal(string goal)
{
if (!Tracker.IsActive || Tracker.Current == null)
{
Tracker.StartTracking();
}
if (Tracker.Current == null)
{
return Json(new { Success = false, Error = "Can't activate tracker" });
}
if (string.IsNullOrEmpty(goal))
{
return Json(new { Success = false, Error = "Goal not set" });
}
var goalRootItem = Sitecore.Context.Database.GetItem(DefaultGoalLocation);
var goalItem = goalRootItem.Axes.GetDescendants().FirstOrDefault(x => x.Name.Equals(goal, StringComparison.InvariantCultureIgnoreCase));
if (goalItem == null)
{
return Json(new { Success = false, Error = "Goal not found" });
}
var page = Tracker.Current.Session.Interaction.PreviousPage;
if (page == null)
{
return Json(new { Success = false, Error = "Page is null" });
}
var registerTheGoal = new PageEventItem(goalItem);
var eventData = page.Register(registerTheGoal);
eventData.Data = goalItem["Description"];
eventData.ItemId = goalItem.ID.Guid;
eventData.DataKey = goalItem.Paths.Path;
Tracker.Current.Interaction.AcceptModifications();
Tracker.Current.CurrentPage.Cancel();
return Json(new { Success = true });
}
}
}
Step 2 - Register a custom MVC route
The next step is to create a custom processor for the initialize pipeline and define custom route in the Process method similar to the following: using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.UI.WebControls;
using Sitecore.Pipelines;
namespace MyNamespace
{
public class RegisterCustomRoute
{
public virtual void Process(PipelineArgs args)
{
Register();
}
public static void Register()
{
RouteTable.Routes.MapRoute("CustomRoute", "MyCustomRoute/{controller}/{action}/{id}");
}
}
}
Add this processor to the initialize pipeline right before the Sitecore InitializeRoutes processor. You can do this with the help of the patch configuration file in the following way:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<initialize>
<processor type="MyNamespace.RegisterCustomRoute, MyAssembly"/>
</initialize>
</pipelines>
</sitecore>
</configuration>
Step 3 - Trigger using jQuery
Finally, trigger the goal by name using a few lines of jQuery: $.post("/MyCustomRoute/Analytics/TriggerGoal?goal=tweet" ,function(data){
//Do something with data object
});
5 comments:
Appreciate the post - saved me a lot of time. Thanks Martin!
Very nice, thanks for this.
Only recommendation: Specify "goal" using jQuery's second parameter (post data) instead of via GET value. Otherwise, be sure to `encodeURIComponent` the goal name when specifying it in the POST URL. e.g.
Modifying your version:
$.post('/MyCustomRoute/Analytics/TriggerGoal?goal=' + encodeURIComponent('tweet'), function(){ ... });
Leveraging jQuery and POSTing like a POST.
$.post('/MyCustomRoute/Analytics/TriggerGoal',{goal:'tweet'},function(){ ... });
Otherwise very helpful!
~Brad
Hey martin, Thank you for this. Why do you need " Tracker.Current.CurrentPage.Cancel();" at the end of the code?
Hi Jose,
If you don't cancel, you would end up seeing the path of the controller action in analytics , which is obviously undesirable.
Cheers!
Post a Comment