Track virtual page views with Sitecore DMS

16 December 2011
Przemek Taront
Frink_Cognifide_2016_HeaderImages_0117

This post concerns Sitecore 6.5.0 (rev. 110818).

The Sitecore DMS keeps track of visitors and visits they make to your CMS website. Every visit is a series of page views and each page view is recorded as a row in the Pages table in the Analytics database. Recording of page views is handled automatically by one of the Sitecore pipelines and it's difficult even for a developer to control. The DMS always records the URL from the current HTTP request accompanied by the GUID of the current item (if there is one).

Google Analytics has its trackPageview() function. It the majority of cases it is called without parameters and it tracks your current URL. However, you can track so called virtual page views by passing any other URL as the parameter. Is it possible in Sitecore? And do we really need it?

There are several situations when you may want to record a completely different URL. For instance, your website has some pages not managed by Sitecore CMS that you still want to track in Sitecore DMS. Whenever a user visits such page you want to call a handler within the Sitecore web application that will record the referring page in the analytics database. In this post I am going to present a sample solution to this problem.

Implementation

Create a new ASPX page in your application's \layouts\system folder, name it TrackExternal.aspx and fill it with some dummy CSS content, i.e.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TrackExternal.aspx.cs"
    Inherits="Cognifide.Sitecore.Helpers.TrackExternal" %>
<%@ OutputCache Location="None" VaryByParam="none" %>
.sc_visitor {
}
In the code behind override the OnInit method:
protected override void OnInit(EventArgs e)
{
  base.Response.ContentType = "text/css";

  if (Context.Diagnostics.Tracing || Context.Diagnostics.Profiling)
    return;

  if (Tracker.IsActive && (Tracker.Visitor.VisitorClassification == 0x39d))
  {
    typeof (VisitorCssPage).InvokeMember("UpdateVisitorIdentification",
        BindingFlags.InvokeMethod | BindingFlags.Static |
        BindingFlags.NonPublic, null, null, null);
  }

  if (HttpContext.Current == null)
    return;

  if (HttpContext.Current.Request.UrlReferrer == null)
    return;

  string urlToTrack = HttpContext.Current.Request.UrlReferrer.AbsolutePath;
  Tracker.CurrentPage.Url = urlToTrack;
  Tracker.CurrentPage.UrlText = urlToTrack;
}
You will need the following namespaces in your code behind:
using System.Reflection;
using System.Web;
using Sitecore;
using Sitecore.Analytics;
using Sitecore.Shell.Applications.Analytics;
Code in lines 5-13 invokes the logic normally handled by Sitecore's VisitorIdentification control. We have to use reflection here in order to get to the private UpdateVisitorIdentification method.

The last two lines of the OnInit method replace the URL being tracked, so instead of recording /layouts/system/TrackExternal.aspx Sitecore will save the URL of the referrer.

Usage

For each non-Sitecore page you want to track, add the following line to its <head> section.
<link rel="stylesheet" type="text/css"
    href="http://sitecore.cognifide.com/layouts/system/TrackExternal.aspx" />
From now on every page view will be recorded in the analytics database. The only difference is that ItemId column in the Pages table will equal to an empty GUID for non-Sitecore pages. Note that if a visitor has not been to your site before, TrackExternal will create analytics cookies first.

I hope you have enjoyed my post. Maybe you know a different solution to this problem. Feel free to write your thoughts below.