---
title: Custom tracking
slug: cms-12/docs/custom-tracking
docTags: 
createdAt: 2026-08-10T15:55:54.000Z
---

You can track anything you like using Profile Store.

1. Create FormsSubmission tracker class.

```csharp
public class FormsSubmissionTracker
  {
  }
```

2. Add necessary dependencies.
   There are the following dependencies to three classes:
   - ITrackingService. Will be used to send the tracking data.
   - ISiteDefinitionResolver. Will be used to get SiteId.

```csharp
public class FormsSubmissionTracker
  {
    private readonly ITrackingService _trackingService;
    private readonly ISiteDefinitionResolver _siteDefinitionResolver;
    private const string FormsTrackingEventType = "epiFormsTracking";
    public FormsSubmissionTracker(ITrackingService trackingService, ISiteDefinitionResolver siteDefinitionResolver)
      {
        _trackingService = trackingService;
        _siteDefinitionResolver = siteDefinitionResolver;
      }
  }
```

3. Create a method for tracking forms submission.
   Create an async method for sending page view tracking events to be async all the way.
   The method has two dependencies:
   - IContent. The forms content that is being tracked.
   - HttpContextBase. Is needed in the Track method of ITrackingService.

```csharp
public async Task Track(IContent formsContent, HttpContextBase httpContextBase)
   {
   }
```

4. Create model classes for tracking forms submission.
   Track the following of the submitted forms:
   - Name. The name of the form.
   - ContentGuid. The id of the form.
   - SiteId. The site this form belongs to.

```csharp
public class FormsSubmissionTrackingModel
  {
    public string Name { get; set; }
    public Guid ContentGuid { get; set; }
    public Guid SiteId { get; set; }
  }
```

5. Create instance of model in the Track method.
   Use SiteDefinitionResolver to get the site for the content. Then create an instance of the class just created.

```csharp
var site = _siteDefinitionResolver.GetByContent(formsContent.ContentLink, true);
var formstTrackingModel = new FormsSubmissionTrackingModel
  {
    Name = formsContent.Name,
    ContentGuid = formsContent.ContentGuid,
    SiteId = site.Id
  };
```

6. Create a method for getting UserData.
   Obtain the name and email of the user, if possible. This example uses **EPiServer.Security.PrincipalInfo** for the name and **EPiServer.Personalization.EPiServerProfile** for the email.

```csharp
private static UserData CreateUserData(HttpContextBase httpContextBase)
  {
    var name = EPiServer.Security.PrincipalInfo.CurrentPrincipal?.Identity?.Name;
    var email = EPiServer.Personalization.EPiServerProfile.Current?.Email;
    return new UserData()
      {
        Name = name,
        Email = email
      };
  }
```

7. Create TrackingData instance.
   Create an instance of trackingData, where the generic type is our tracking model. Then set the properties:
   - EventType. Schema name for the tracking event.
   - User. UserData created in the CreateUserData method.
   - Value. A human readable text about the event that will be created.
   - Payload. An instance of the generic type, containing all properties with values needed for the specific event.

```csharp
var value = $"Form {formsContent.Name} submitted";
var user = CreateUserData(httpContextBase);
var trackingData = new TrackingData<FormsSubmissionTrackingModel>
  {
    EventType = FormsTrackingEventType,
    User = user,
    Value = value,
    Payload = formstTrackingModel
  };
```

8. Send tracking data.
   The last thing to do is call the tracking service with the trackingData, and HttpContextBase.

```csharp
await _trackingService.Track(trackingData, httpContextBase);
```

## FormsSubmissionTracker class summary

Here is a summary of the whole class:

```csharp
public class FormsSubmissionTracker
  {
    private readonly ITrackingService _trackingService;
    private readonly ISiteDefinitionResolver _siteDefinitionResolver;
    private const string FormsTrackingEventType = "epiFormsTracking";
    public FormsSubmissionTracker(ITrackingService trackingService, ISiteDefinitionResolver siteDefinitionResolver)
      {
        _trackingService = trackingService;
        _siteDefinitionResolver = siteDefinitionResolver;
      }
    public async Task Track(IContent formsContent, HttpContextBase httpContextBase)
      {
        var site = _siteDefinitionResolver.GetByContent(formsContent.ContentLink, true);
        var formstTrackingModel = new FormsSubmissionTrackingModel
          {
            Name = formsContent.Name,
            ContentGuid = formsContent.ContentGuid,
            SiteId = site.Id
          };
        var value = $"Form {formsContent.Name} submitted";
        var user = CreateUserData(httpContextBase);
        var trackingData = new TrackingData<FormsSubmissionTrackingModel>
          {
            EventType = FormsTrackingEventType,
            User = user,
            Value = value,
            Payload = formstTrackingModel
          };
        await _trackingService.Track(trackingData, httpContextBase);
      }
    private static UserData CreateUserData(HttpContextBase httpContextBase)
      {
        var name = EPiServer.Security.PrincipalInfo.CurrentPrincipal?.Identity?.Name;
        var email = EPiServer.Personalization.EPiServerProfile.Current?.Email;
        return new UserData()
          {
            Name = name,
            Email = email
          };
      }
  }
```

## Use FormsSubmissionTracker class

You can now take a dependency to FormsSubmissionTracker when a forms is being submitted, and call the Track method in this class.
