How to: Collect Custom Tracking Data using a Custom Facet in Sitecore 8

Out of the box, Sitecore provides a number of attributes you can collect about your website visitors in order to provide a personalized experience and produce meaningful reporting. In this tutorial, we’ll look at how to collect your own custom attributes based associated with users that may not exist in Sitecore. For this tutorial, we will assume your customer just made a purchase or payment of some sort to your business and we want to track their last payment amount and date.

Sitecore Versions:

  • Sitecore 8.x

Note: The implementation for how to work with Facets changes slightly in Sitecore 9.x. I’ll be producing another post in the future on how to do this in 9.x.


Step 1: Creating the Custom Facet

The first step we need to take to collect our custom user attributes is to create a new Interface and Class. Since our example is associated with a visitor’s last payment amount and date, we’ll name our Interface and Class ICustomerPaymentFacet and CustomerPaymentFacet respectively.

using Sitecore.Analytics.Model.Framework;
using System;
namespace MyNamespace.Facets
public interface ICustomerPaymentFacet : IFacet
decimal LastPaymentAmount { get; set; }
DateTime LastPaymentDate { get; set; }
public class CustomerPaymentFacet : Facet, ICustomerPaymentFacet
public CustomerPaymentFacet()
public decimal LastPaymentAmount { get => GetAttribute<string>(nameof(LastPaymentAmount)); set => SetAttribute(nameof(LastPaymentAmount), value); }
public DateTime LastPaymentDate { get => GetAttribute<string>(nameof(LastPaymentDate)); set => SetAttribute(nameof(LastPaymentDate), value); }
view raw gistfile1.txt hosted with ❤ by GitHub

There are a couple of items worth noting in the above snippet. First, the implementation class must be decorated with the [Serializable] attribute. Since we will be storing this class into the xDB database, being able to serialize and deserialize the information is going to be important.

The next thing to notice is that the interface inherits from the Sitecore.Analytics.Model.Framework.IFacet interface while our class inherits from Sitecore.Analytics.Model.Framework.Facet and implements our own interface. This will be required in order to attach this information to the user’s tracking contact.

Lastly, the implementation of the properties is a bit abnormal compared to declaring properties in a normal C# object. The helper methods of EnsureAttribute<T>(“name”), GetAttribute<T>(“name”), and SetAttribute<T>(“name”) are to ensure our interface members are properly registered with the tracking contact model.

Step 2: Registering the Facet

Now that we the model defined via our interface and our facet implemented, it’s time we tell SItecore that it is ready to use. In order to do this, we need to write a configuration patch file in order to patch the Sitecore.Analytics.Model.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch=""&gt;
<element interface="MyNamespace.Facet.IContactPortalInfo, MyNamespace" implementation="MyNamespace.Facet.ContactPortalInfo, MyNamespace"/>
<facet name="Payment" contract="MyNamespace.Facets.IContactPortalInfo, MyNamespace" />
MyNamespace.Facets.ContactPortalInfo, MyNamespace
view raw gistfile1.txt hosted with ❤ by GitHub

Save the above snippet in your App_Config folder to patch it into the Sitecore’s configuration. There are 3 section to the above snippet so let’s walk through them now.

The first section defines where our new field definitions are for the tracking model. This is defined in the <elements> section of the snippet.

The second section defines how to expose our model properties by way of the <contact> section. In this instance, we’re appending a new facet to the existing collection. Sitecore will take our model definition and populate the contact using the facet we provided.

The third section patches the Sitecore.SessionSerialization.config file which is used when running a multiple CD servers in your environment. This section simply registers our type to be serialized into session state.

Step 3: Reading and Writing

Now that the facet is defined and registered, we can write code to help us read and write the information we wish to track of our users.

In both reading and writing scenarios, you will need to ensure that the user’s tracking contact is available. If VIsitor Tracking is not enabled on your site, none of the following code act properly.

using System;
using Sitecore.Analytics;
using Sitecore.Analytics.Model.Entities;
namespace MyNamespace.Repositories
public interface IPaymentFacetRepository
void SetFacentInformation(string userIdentifier, decimal lastPaymentAmount, DateTime lastPaymentDate);
public class PaymentFacetRepository : IPaymentFacetRepository
public void SetFacentInformation(string userIdentifier, decimal lastPaymentAmount, DateTime lastPaymentDate)
if (Tracker.Current?.Session?.Contact != null)
var contact = Tracker.Current.Session.Contact;
if (string.IsNullOrWhiteSpace(contact.Identifiers.Identifier))
var paymentFacet = contact.GetFacet<ICustomerPaymentFacet>("Payment");
paymentFacet.LastPaymentAmount = lastPaymentAmount;
paymentFacet.LastPaymentDate = lastPaymentDate;
catch (Exception ex)
// Log Exception here.
view raw gistfile1.txt hosted with ❤ by GitHub

In this snippet, we define a repository class that will be used to set the properties we defined in our facet earlier. The SetFacentInformation function defines 3 parameters. The first is used to identify the user. If the user is not identified, the facet settings will exist for the user for the session; however, it will not be persisted to the xDB database for future use. The second and third parameters are the values we wish to track.

The first thing we do inside of the SetFacentInformation function is ensure visitor tracking is enabled on this user’s session. If it is not, we there is no object to append our data to.

Next, we identify the user if they have not been identified so far this session. Again, it is very important to identify your users so that the tracking information is stored to the xDB database. Unidentified (Anonymous) users are not stored in the xDB database for performance reasons and their return visits will be reset.

Lastly, we retrieve our user’s Payment facet which we defined in our configuration patch file. Once this facet has been retrieved, we can set the properties of the facet by reference with no explicit call to save the information. In Sitecore 8.x, the values we set are persisted for the session and, if the user is identified, will be persisted to the xDB database at the end of the current user session.

By retrieving our user’s Payment facet we also have the option to read any existing values that are saved to the xDB database from a previous session or earlier in the current session. If we wish to create a custom personalization rule around these values, we would simply retrieve the facet as we did in this example and read the properties. But that is the topic of a latter post.

Additional Resources

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close