Use tracking in CMS to provide content recommendations, and for tracking data to any source for business intelligence data visualization purposes.
## Tracking
The tracking service supports product-specific tracking for Optimizely CMS. Depending on the setup, you can track Optimizely CMS data to any source, or to Optimizely Profile Store. To get tracking running for a site, you need to configure access to the tracking API.
### Install and configure
See [Install and configure tracking](🔗).
### Schema and name for page view tracking in Payload
The following schema is used for page view tracking. It's possible to extend the tracking event with extra fields. It is important that the following fields are included in correct structure.
To get most out of the event, the name for page view tracking must be epiPageView. Several Optimizely internal services will aggregate the known fields in the event with the event name epiPageView.
### Track page views using ITrackingService
There are several ways to enable Page view tracking. The best combination of freedom and schema rules is provided via the _EPiServer.Tracking.PageView_ Nuget package in combination with the ITrackingService. The following example guides you through a class that tracks page views.
Create the page view tracker class.
Add necessary dependencies to three classes:
ITrackingService. Sends the tracking data.
ISiteDefinitionResolver. Gets SiteId.
IContentLoader. Gets "Ancestors" for the page.
Create a method for tracking page views.
Create an async method for sending page view tracking events. This lets you be async all the way. The method has two dependencies:
PageData. The page being tracked.
HttpContextBase. Needed in the Track method of  ITrackingService.

Create an instance of EPiPageViewWrapper in the Track method.The _EPiServer.Tracking.PageView_  package contains tracking models that help track page views in a specific way. Internal Optimizely services can make greater use of page view tracking events when the schema is known.
Use SiteDefinitionResolver to get the site for the content, and IContentLoader to get the ancestors.
The EpiPageViewWrapper model is just a "wrapper" model, which contains a property named Epi of type EpiPageView. EpiPageView contains the necessary properties to be set:
ContentGuid. Identifier of page being tracked.
Language. Language of page being tracked.
SiteId. Identifier of the site to which page belongs.
Ancestors. The page's ancestors.
Create a method for getting UserData.
You want to get the user's name and email address if possible. This example uses EPiServer.Security.PrincipalInfo for the name and EPiServer.Personalization.EPiServerProfile for the email.
Create a TrackingData instance.
Create an instance of "tracking data," where the generic type is our tracking model. Then, set the following 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.
Send tracking data.
Call the tracking service with the tracking data and HttpContextBase.

### PageViewTracking class
The following code is a summary of the whole class.
You can use the PageViewTracking class from any part of the site where HttpContext is available. The following is an example of using the class from an async controller action.
### Track page views using a tracking attribute
An alternative to ITrackingService is to use a tracking attribute. Add the PageViewTracking attribute to your controller, and the page will be tracked.