📚 Product Knowledge
Personalization Visitor Groups
📖 Docs

Personalization & Visitor Groups - Optimizely CMS 12

Exam Area: Area 1 – Product Knowledge (15%) Reference: https://docs.developers.optimizely.com/content-management-system/docs/visitor-groups


1. What is Personalisation?

Personalization in CMS 12 lets editors show different content to different audiences without developer involvement. It is based on Visitor Groups.

Visitor Group: "Returning Visitors from Sweden"
  Criteria:
    + Geographic location: Country = Sweden
    + Visit count: > 3

Content personalised for this group:
  → Hero banner: Swedish-specific offer
  → CTA button: "Visa erbjudande"

2. Visitor Groups

A Visitor Group is a named segment defined by one or more criteria:

Criterion TypeExample
Geographic LocationCountry = "United Kingdom"
Browser typeFirefox / Chrome / Safari
Time of dayBetween 09:00 and 17:00
Number of visitsMore than 5 visits
Role membershipUser is in "PremiumCustomers" role
Query string?campaign=summer2024
Referring URLCame from Google
Custom criterion(developed by the team)

3. Creating Visitor Groups

Admin → Visitor Groups → Create new
  → Name: "Returning UK Visitors"
  → Add criterion: Geographic Location → Country = UK
  → Add criterion: Number of visits > 2
  → Logic: All criteria must match (AND) / Any (OR)
  → Save

4. Using Visitor Groups on Content

In Edit View, editors personalise Content Area items:

Content Area → Add block → Right-click block → "Personalise"
  → Select Visitor Group: "Returning UK Visitors"
  → This block is only shown to matching visitors

Multiple blocks can be added to the same area slot with different visitor groups — CMS shows the first matching one.


5. Checking Visitor Group in Code

using EPiServer.Personalization.VisitorGroups;

public class PersonalisationService
{
    private readonly IVisitorGroupRoleRepository _visitorGroupRepo;
    private readonly IVisitorGroupRepository    _repository;

    public PersonalisationService(
        IVisitorGroupRoleRepository visitorGroupRoleRepo,
        IVisitorGroupRepository repository)
    {
        _visitorGroupRepo = visitorGroupRoleRepo;
        _repository       = repository;
    }

    public bool IsInGroup(string groupName, IPrincipal user, HttpContext context)
    {
        // Uses the visitor group role provider
        return context.User.IsInRole("G:" + groupName);
    }

    public IEnumerable<VisitorGroup> GetAllGroups()
        => _repository.List();
}

6. Custom Visitor Group Criterion

[VisitorGroupCriterion(
    Category    = "Custom",
    DisplayName = "First Time Visitor",
    Description = "True if the visitor has never been to the site before")]
public class FirstTimeVisitorCriterion : CriterionBase<EmptyCriterionModel>
{
    public override bool IsMatch(IPrincipal principal, HttpContext httpContext)
    {
        // Check if visitor has a "visited" cookie
        return !httpContext.Request.Cookies.ContainsKey("_visited");
    }
}

7. Previewing Personalised Content

Editors can preview what the site looks like for a specific visitor group:

Edit View → Context Panel → Visitor Groups gadget
  → Select group: "Returning UK Visitors"
  → Preview renders as if the current user is in that group

8. Visitor Groups and Caching

CRITICAL: Personalised content must NOT be cached by CDN or output cache, because different visitors see different content from the same URL.

// Mark responses with personalised content as private/no-cache
Response.Headers["Cache-Control"] = "private, no-store";

// OR use VaryBy headers if using server-side output cache
[ResponseCache(VaryByHeader = "Cookie", Duration = 0)]

9. IVisitorGroupRepository

// Get all visitor groups
var groups = _visitorGroupRepository.List();

// Get specific group
var group = _visitorGroupRepository.Load("group-guid");

// Save custom group programmatically
_visitorGroupRepository.Save(new VisitorGroup
{
    Name = "VIP Customers",
    Criterias = new List<VisitorGroupCriteria> { ... }
});

Review Questions

  1. What is a Visitor Group? (A named audience segment defined by one or more criteria — used for content personalisation)
  2. What happens when multiple personalised blocks are in the same Content Area slot? (CMS shows the first block whose Visitor Group matches the current visitor)
  3. Why must personalised content not be cached? (Different visitors see different content from the same URL — caching would serve wrong content)
  4. How do editors preview personalised content? (Context Panel → Visitor Groups gadget → select a group → preview re-renders for that group)
  5. What is required to create a custom visitor group criterion? (Inherit from CriterionBase<T> and decorate with [VisitorGroupCriterion])