---
title: Logging custom A/B testing conversions
related:
  - https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/a-b-testing-pages.md
  - https://docs.kentico.com/13/on-line-marketing-features/configuring-and-customizing-your-on-line-marketing-features/enabling-a-b-testing.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

> **Info:** **Enterprise license required**
>
> Features described on this page require the **Kentico Xperience Enterprise** license.

Conversions represent actions performed by the site's visitors, and are used to evaluate different variants of pages during [A/B testing](https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/a-b-testing-pages.md).

The system provides a default set of conversions for the most common types of visitor actions, but developers can also extend the A/B testing conversion functionality. See the following customization scenarios:

## Registering custom conversion types

Use the following approach to register custom conversion types for A/B testing:

1. Open the solution of your **Xperience administration project** in Visual Studio (using the _WebApp.sln_ file).
2. Add a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md) and override the module's **OnInit** method:
3. For each conversion type, prepare an object of the **ABTestConversionDefinition** class. The constructor accepts the following string parameters:

   - _Name_ – a unique identifier of the conversion type. Used in the API when [logging conversions](#logging-conversions-in-custom-code).

     > **Tip:** **Tip**: If you have multiple custom conversion types, create a separate class with constants storing the names (identifiers). You can then [share the code](https://docs.kentico.com/13/custom-development/applying-customizations-in-the-xperience-environment.md) between your administration and MVC applications, and use the constants when logging the conversions.
   - _Display name_ – the name shown to marketers in the administration interface when defining conversions for A/B tests. Can be localized by setting the value to an expression in format _**{$key$}**_. Replace "key" with the key of a [resource string](https://docs.kentico.com/13/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md).
4. Call the **ABTestConversionDefinitionRegister.Instance.Register** method with the _ABTestConversionDefinition_ object as a parameter.

   ```csharp title="Basic example"

   using CMS;
   using CMS.DataEngine;

   using CMS.OnlineMarketing;

   // Registers the custom module into the system
   [assembly: RegisterModule(typeof(CustomABTestingModule))]

   public class CustomABTestingModule : Module
   {
       // Module class constructor, the system registers the module under the name "CustomABTesting"
       public CustomABTestingModule()
           : base("CustomABTesting")
       {
       }

       // Contains initialization code that is executed when the application starts
       protected override void OnInit()
       {
           base.OnInit();

           // Defines a custom conversion type
           var conversionTypeDefinition = new ABTestConversionDefinition("CustomConversion", "Custom conversion");

           // Registers the custom conversion type
           ABTestConversionDefinitionRegister.Instance.Register(conversionTypeDefinition);
       }
   }

   ```
5. Rebuild the solution.

Marketers can now select the registered conversion types when configuring tests in the **A/B tests** application of the administration interface. Custom conversion types appear among the default types (the overall list is sorted in alphabetical order according to the display names).

Custom conversion types are not logged automatically. Developers need to adjust the code of the MVC live site application, and log the conversions in the appropriate location using the API. See [Logging conversions in custom code](#logging-conversions-in-custom-code).

### Defining configurable conversion types

Some types of conversions require additional input, such as an identifier of a related object or other type of condition. For example, marketers need to select a specific newsletter when adding the default _Newsletter subscription_ conversion type to an A/B test. The system then only logs the conversion when a visitor subscribes to the selected newsletter (not any newsletter in general).

The user interface of the configuration input is provided by a [form control](https://docs.kentico.com/13/custom-development/extending-the-administration-interface/developing-form-controls.md), which is specified in the registration code of the conversion type.

Developers can leverage this type of configuration for custom conversion types:

1. Edit the code where the conversion type's _ABTestConversionDefinition_ object is defined.
2. Specify the form control used for the configuration input – prepare an object of the **ABTestFormControlDefinition** class. The constructor accepts the following parameters:
   - _Form control_ – identifies the form control. Two options are available:
     - a string matching the _Code name_ of the form control (you can find the code names on the _Form controls_ tab of the _Administration interface_ application within the Xperience administration interface)\
       – or –
     - the _System.Type_ of the form control class (i.e. a class inheriting from _FormEngineUserControl_)
   - _Input caption_ – the text of the label displayed before the input to marketers in the A/B test configuration interface. Can be localized by setting the value to an expression in format _**{$key$}**_. Replace "key" with the key of a [resource string](https://docs.kentico.com/13/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md).
   - (Optional) _Form control parameters_ – an [IDictionary](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.idictionary-2) collection that can be used to set the form control's [parameters](https://docs.kentico.com/13/custom-development/extending-the-administration-interface/developing-form-controls/defining-form-control-parameters.md). Each key must match the name of a parameter and have a value of the appropriate type.
3. Add the _ABTestFormControlDefinition_ object as another parameter of the conversion type's _ABTestConversionDefinition_ constructor.
4. Rebuild the solution.

For example, the following code registers a custom conversion type with a "Day of the week" selector based on the system's _Drop-down list_ form control:

```csharp title="Advanced example"

using System;
using System.Collections.Generic;

using CMS.OnlineMarketing;

...

// Contains initialization code that is executed when the application starts
protected override void OnInit()
{
    base.OnInit(); 

    // Prepares option parameters for a Drop-down list form control (days of the work week)
    var options = new List<string> {
        DayOfWeek.Monday.ToString(),
        DayOfWeek.Tuesday.ToString(),
        DayOfWeek.Wednesday.ToString(),
        DayOfWeek.Thursday.ToString(),
        DayOfWeek.Friday.ToString() 
    }; 

    // Prepares a definition for a 'Drop-down list' form control containing the specified options
    var formControlDefinition = new ABTestFormControlDefinition(
        "DropDownListControl",
        "Day of the week",
        new Dictionary<string, object> { { "options", String.Join(Environment.NewLine, options) } }
    );

    // Defines a custom conversion type with an input field that allows users to select a day of the week
    var advancedConversionTypeDefinition = new ABTestConversionDefinition("AdvancedConversion", "Advanced conversion", formControlDefinition);

    // Registers the custom conversion type
    ABTestConversionDefinitionRegister.Instance.Register(advancedConversionTypeDefinition);
}

```

When marketers add this advanced custom conversion type to a test in the **A/B tests** application, they can select a day of the work week.

![Adding a configurable conversion to a test](https://docs.kentico.com/docsassets/13/logging-custom-a-b-testing-conversions/Advanced_Conversion_Type_UI.png "Adding a configurable conversion to a test")

The selected day limits when conversions of this type are logged. Developers need to ensure that the condition is reflected in the code used to log the custom conversions (by supplying an _Item identifier_ value matching the name of the current day). For more information, see [Logging conversions in custom code](#logging-conversions-in-custom-code).

## Logging conversions in custom code

The Xperience API allows developers to extend the A/B testing functionality by logging conversions in any location within the website's code. Custom logging is possible for both [custom registered conversion types](#registering-custom-conversion-types) and the system's default types.

1. Open the solution of your **MVC live site project** in Visual Studio.
2. Identify the part of your site's code where you wish to log the conversion (for example in a controller action that displays a specific page or handles a related event).
3. Get an instance of the **IABTestConversionLogger** service (available in the _CMS.OnlineMarketing_ namespace) and call the **LogConversion** method. Specify the following required parameters:

   - _Conversion name_ – the name (unique identifier) of the conversion type that you wish to log. The names of the default conversion types are available as constants within the **ABTestConversionNames** class (found in the _CMS.OnlineMarketing_ namespace).
   - _Site name_ – the code name of the current site.
4. When logging conversion types that have a configuration input, you also need to set a third parameter for the _LogConversion_ method:

   - _Item identifier_ – an identifier (string) of the object related to the logged conversion, or another conditional value based on the context in which the conversion is being logged.

     The conversion is  _**only logged**_  if the supplied _Item identifier_ matches the value saved by the configuration input's form control for the given A/B test. For example, the default _Newsletter subscription_ conversion type requires marketers to select a specific newsletter, which saves the given newsletter's code name into the configuration of the given A/B test. When a newsletter subscription occurs, the given newsletter's code name is supplied as the item identifier, so conversions are only logged if there is a match with the configuration of the related A/B test.

   > **Info:** **LogConversion optional parameters**
   >
   > Additionally, the following optional parameters are available for the _LogConversion_ method:
   >
   > - _Default value_ – decimal that sets the default value logged for the conversion. Only used if a different _Value_ is not specified in the conversion settings for the given A/B test.
   > - _Count_ – integer that sets the number of logged conversion hits.
   > - _Culture_ – the culture code with which the conversion is logged (i.e. the website language version selected by the visitor performing the conversion). If not specified, the application's current thread culture is used.
5. Rebuild the solution.

```csharp title="Examples"

using System;

using CMS.Base;
using CMS.OnlineMarketing;

...

// Instance of the A/B test conversion logging service
private readonly IABTestConversionLogger abTestConversionLogger;
// Instance of a service used to get the name of the current site
private readonly ISiteService siteService;

// Example of a controller constructor that initializes service instances using dependency injection
public PageController(IABTestConversionLogger abTestConversionLogger, ISiteService siteService)
{
    this.abTestConversionLogger = abTestConversionLogger;
    this.siteService= siteService;
}

...

// Logs a hit for the default user registration conversion type
abTestConversionLogger.LogConversion(ABTestConversionNames.USER_REGISTRATION, siteService.CurrentSite.SiteName);

// Logs a hit for a custom conversion type with the 'CustomConversion' name
abTestConversionLogger.LogConversion("CustomConversion", siteService.CurrentSite.SiteName);

// Logs a hit for a custom conversion type with the 'AdvancedConversion' name
// Supplies the name of the current day of the week as the item identifier, 
// which ensures that the conversion is only logged if there is a match with the selected day in the A/B test configuration
abTestConversionLogger.LogConversion("AdvancedConversion", siteService.CurrentSite.SiteName, DateTime.Now.ToString("dddd"));

```
