Sitecore personalisation with profile keys

Personalisation based on highest ranking profile key

The tricky aspects of setting up personalisation include deciding on:

  1. Personas

  2. Profile keys and scores for the personas.

Overlapping factors in the profile keys and scores, and a user transitioning from one persona to another, might be a challenge that needs overcoming.

If you need support in defining the personalisation framework, 8 creative ways to define Sitecore personas is a great reference on best practice strategies.


For this example:

  1. Your components and pages need to be experience editor friendly and compatible. Setting up and testing personalisation from the presentation details tab in the tree content editor will be very difficult to maintain and test long term.

  2. Your components should use datasources. To enable personalisation, your components should be able to alter where it reads data from based on how visitors are segmented. Regardless of whether or not there is an immediate requirement to personalise, using datasources means you can in the future and will ensure A/B testing can be done without needing to rework components.

Get started

For this example personalisation will be based on the highest scoring profile key within a profile - think of the profile as a topic and the profile key as the subject matter.

For the purpose of the example, the following use cases will be used: Imagine the need is to segment potential car buyers based on their interest in different vehicle body types, if they return to the front page the hero image can be personalised to show the preferred body type based on their browsing behaviour.

Below is an example of how the content can be segmented:


Sitecore Content Setup

  1. Login to Sitecore and open the “Marketing Control Panel”.


2. Navigate to “Profiles” (/sitecore/system/Marketing Control Panel/Profiles) and make a new Profile called “Preferred Body Type”.


3. Create new “Profile Keys” for SUV, Sedan, Coupe, Hatch & Pickup under your new “Profile”. Set the min to 0 and max value to 10.


4. Next we will assign scores to some of our content, Go to your content and click on the “Profile Card” icon in the top right of your content item


Assign an appropriate score to one or many of the profile keys on your content item.


Creating a custom condition in rules

To compare profile values to one another a new Sitecore rule is required. The rule that ships with Sitecore can only compare a profile value to a static value. Below is the code that will compare the values:

using Sitecore.Analytics;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Rules;
using Sitecore.Rules.Conditions;
using System;

namespace MyAssembly
    public class ProfileCompareToProfileCondition<T> : OperatorCondition<T> where T : RuleContext
        private string profileKeyId;
        private string profileKeyId2;

        public string ProfileKeyId
                return profileKeyId ?? string.Empty;
                Assert.ArgumentNotNull(value, "value");
                profileKeyId = value;

        public string ProfileKeyId2
                return profileKeyId2 ?? string.Empty;
                Assert.ArgumentNotNull(value, "value");
                profileKeyId2 = value;

        public ProfileCompareToProfileCondition()
            profileKeyId = string.Empty;
            profileKeyId2 = string.Empty;

        protected override bool Execute(T ruleContext)
            Assert.ArgumentNotNull(ruleContext, "ruleContext");
            double profileKeyValue1 = GetProfileKeyValue(ProfileKeyId);
            double profileKeyValue2 = GetProfileKeyValue(ProfileKeyId2);
            switch (GetOperator())
                case ConditionOperator.Equal:
                    return Math.Abs(profileKeyValue1 - profileKeyValue2) < 0.001;
                case ConditionOperator.GreaterThanOrEqual: return profileKeyValue1 >= profileKeyValue2;
                case ConditionOperator.GreaterThan:
                    return profileKeyValue1 > profileKeyValue2;
                case ConditionOperator.LessThanOrEqual:
                    return profileKeyValue1 <= profileKeyValue2;
                case ConditionOperator.LessThan:
                    return profileKeyValue1 < profileKeyValue2;
                case ConditionOperator.NotEqual: return Math.Abs(profileKeyValue1 - profileKeyValue2) > 0.001;
                    return false;

    private double GetProfileKeyValue(string profileKey)
        double profileKeyScore = 0.0;
        if (!string.IsNullOrEmpty(profileKey))
            Item obj = Tracker.DefinitionDatabase.GetItem(profileKey);
            if (obj != null)
                Item parent = obj.Parent;
                if (parent != null)
                    string profileKeyName = obj.Name;
                    string profileName = parent.Name;

                    var profileDetails = Tracker.Current.Interaction.Profiles[profileName];
                    if (profileDetails != null)
                        profileKeyScore = profileDetails[profileKeyName];

        return profileKeyScore;

Creating the Sitecore Rule

In order to use the new condition a new rule needs to be added to Sitecore:
Create a new condition here: “/sitecore/system/Settings/Rules/Definitions/Elements/Visit/”
Call the new Condition “Profile Compares to Profile”
In the “Text” field enter

where the value of the [profilekeyid,ProfileKey,,specific] profile key [operatorid,Operator,,compares to] [profilekeyid2,ProfileKey,,specific] profile key

In “Type” enter the fully qualified namespace and assembly name



Creating Predefined Rules

With our new rule we can compare two profile keys to determine which is bigger, this is very helpful but needs to compare each profile key to all of the others to correctly determine if its the biggest. Building this complex rule over and over again would be less than ideal so we will create a predefined rule and re-use it wherever we want to personalise some content.

  1. Navigate to “/sitecore/system/Marketing Control Panel/Personalization/Predefined Rules”

And create a new “Conditional Rendering Rule” called “visitor prefers SUV”

2. Choose edit rule and search for “profile key”. Choose the “where the value of the specific profile key compares to specific profile key


3. Now configure the rule and compare SUV to all the other profile keys. The end result should look like this:


Bringing it all together

  1. Go to your page you want to personalise and launch into experience editor


2. Once in experience editor choose the control you want to personalise and click the “Create or edit personalisation for this component button”


3. Hit the “+” button in the top right


4. Give the new rule a name, Lets call it “Prefers SUV”

5. Click on “Edit rule” and choose “where predefined rule is true”, pick your predefined rule you created in the previous step called “visitor prefers SUV”, Click OK

6. Now choose your content to show on the right hand side.


7. You should now be able to preview the content in experience editor as it will be displayed to a segmented user.


Nice to have

Sometimes it would be useful to see the aggregated profile key scores on the front end of the website when browsing like an end user.
This could be helpful in:

  • Troubleshooting problems,

  • Demonstrating personalisation to others and

  • Testing your page. (Sometimes the experience editor view will not include fancy javascript components that would otherwise work on the normal front end)

The below control is a Sitecore MVC controller rendering. (Make sure you are using an MVC Layout otherwise this control will not render).

It can be activated on the public facing site but adding the control to any page and then adding the querystring ?psv=1 at the end of the URL. Be sure to add additional security around this if you are going to ship this feature to production.


using Sitecore.Analytics;
using Sitecore.Mvc.Controllers;
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace WebApplication.Controllers
public class ProfileScoreViewerController : SitecoreController
    // GET: Brochures
    private string cookieKey = "psv";

    public override ActionResult Index()
          Dictionary<string, string> collection = new Dictionary<string, string>();
          bool cookieJustDestroyed = false;
          if (!String.IsNullOrWhiteSpace(Request.QueryString[cookieKey]) && (Request.QueryString[cookieKey] == "false" || Request.QueryString[cookieKey] == "0"))
               Response.Cookies[cookieKey].Expires = DateTime.Now.AddDays(-1);
    cookieJustDestroyed = true;

          if ((!String.IsNullOrWhiteSpace(Request.QueryString[cookieKey]) && (Request.QueryString[cookieKey] == "1" || Request.QueryString[cookieKey] == "true")) || (Request.Cookies[cookieKey] != null && Request.Cookies[cookieKey].Value == "true" && !cookieJustDestroyed))
              var cookie = new HttpCookie(cookieKey, "true");
              cookie.Expires = DateTime.Now.AddDays(1);

              foreach (var profileName in Tracker.Current.Interaction.Profiles.GetProfileNames())
                  var profile = Tracker.Current.Interaction.Profiles[profileName]; //If profile does not exist, it will create that one.

                  foreach (KeyValuePair<string, float> keyValuePair in profile)
                      string key = String.Format("{0} - {1}", profileName, keyValuePair.Key);
                      if (!collection.ContainsKey(key))
                          collection.Add(key, String.Format("{0}", keyValuePair.Value));

          return View("~/Views/ProfileScoreViewer.cshtml", collection);


@model System.Collections.Generic.Dictionary<string, string>
@foreach (KeyValuePair<string, string> kvp in @Model)
    <button><strong>@kvp.Key</strong> @kvp.Value</button>

To find a copy of the code see this Github repo for more details.

This blog post is based on the original post by Jens Gustafsson and updated with some learning and changes for Sitecore 8.2.

Full credit goes to Jens for an excellent article.

Want to talk platform delivery?