---
title: Adding custom web analytics
related:
  - https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/web-analytics.md
  - https://docs.kentico.com/13/on-line-marketing-features/configuring-and-customizing-your-on-line-marketing-features/configuring-web-analytics/web-analytics-api.md
  - https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/web-analytics/viewing-web-analytics-reports.md
  - https://docs.kentico.com/13/configuring-xperience/working-with-system-reports.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).

The system allows you to track custom events as web analytics and display the results in reports within the administration interface.

## Logging analytics in custom code

Developers can use the Xperience API to log web analytics anywhere within the website's code. This is possible for both the default web analytics statistics, as well as custom statistics representing any type of event that you wish to track.

To log web analytics, use the **IAnalyticsLogger** service (available in the _CMS.WebAnalytics_ namespace). The service provides the following methods:

- **Log\*** – methods that log hits for the system's default statistics, for example _LogPageView_ (every statistic has a corresponding method).
- **LogCustomAnalytics** – logs custom statistics under a specified name.

All of the methods require an **AnalyticsData** parameter, which specifies information about the context in which the analytics are logged. The following are the most important properties available. You can set the properties through constructor parameters when creating a new _AnalyticsData_ object:

- **SiteID** – the identifier of the site for which the event is logged.
- **ObjectName / ObjectID** – specifies the context in which the hit was logged. You can use the name or ID of an object, or any custom string. For example, when logging the default page view statistic, the system stores the URL of the current page as the _ObjectName_.
- **Hits** – sets the amount of hits added to the statistic. This parameter is optional and the default value (1) is used if not specified.
- **Value** – specifies a special value for the hit. This parameter is optional and can be used to assign weight to the hit according to some conditions. The value of a statistic is cumulative, which means that each hit adds to the total value logged for the given analytics record (specified by the &#x4F;_&#x62;jectName_ or _ObjectID_).
- **Culture** – specifies the culture code under which the system logs the event. This parameter is optional, and the hit is logged without a culture context if not specified.

See the example below to learn more.

## Example

The following example demonstrates how to log a basic button click as a custom web analytics statistic. You can use the same approach to implement tracking for any type of event on your website.

### Logging the event

Implement the MVC code that presents the button and handles clicks:

1. Open your live site project in Visual Studio.
2. Create a new controller class or edit an existing one.
3. Add an action that handles button click requests (for example as a POST action). Use the **IAnalyticsLogger** service to log a custom analytics hit.

   ```csharp title="Example"

   using System.Web.Mvc;

   using CMS.Base;
   using CMS.WebAnalytics;

   public class HomeController : Controller
   {
       // Instance of the web analytics logging service
       private readonly IAnalyticsLogger analyticsLogger;
       // 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 HomeController(IAnalyticsLogger analyticsLogger, ISiteService siteService) 
       {
           this.analyticsLogger = analyticsLogger;
           this.siteService = siteService;
       }

       public ActionResult Index()
       {
           return View();
       }

       [HttpPost]
       [ValidateAntiForgeryToken]
       public ActionResult ButtonClick()
       {
           // String that indicates whether the current user is authenticated
           string authStatus = "public";
           if (User.Identity.IsAuthenticated)
           {
               authStatus = "authenticated";
           }

           // Prepares an object representing the logging context
           AnalyticsData data = new AnalyticsData(siteService.CurrentSite.SiteID, objectName: authStatus, hits: 1, value: 1);

           // Logs a web analytics hit for the 'buttonclicked' custom statistic
           analyticsLogger.LogCustomAnalytics("buttonclicked", data);

           return RedirectToAction("Index");
       }
   }

   ```
4. Add a button element to the view displayed by the adjusted controller (an _Index_ view based on the sample code above):

   ```xml

   @using (Html.BeginForm("ButtonClick", "Home"))
   {
       @Html.AntiForgeryToken()
       <input type="submit" value="Custom click" />
   }

   ```
5. Save the changes and Build your solution.

When a user clicks the button, the API logs an analytics hit. The resulting data stores the amount of clicks and indicates whether the user who clicked the button was authenticated. Once the data is stored in the database, it can be loaded and displayed in the Web analytics application.

Open the corresponding page on the live site and click the **Custom click** button several times. Try doing this while signed in and also as an unauthenticated public visitor.

### Creating reports for statistics

Before users can view the statistics of the button click event in the **Web analytics** application, you need to create reports for displaying the data of the custom statistic. Most statistics have _five types of reports_: hourly, daily, weekly, monthly and yearly.

1. Open the **Reporting** application and select the **Web Analytics** category in the tree.

   - The sub‑categories contain reports used by the default statistics such as page views, traffic sources, etc.

2. Click **...** next to the **New report** button above the tree and select **New category** in the menu.

3. Type _Button clicks_ as the **Category display name** and click **Save**.

4. Create a daily report for the new statistic. Click **New report** and enter the following values:

   - **Report display name**: Button clicked - daily report
   - **Report name**: buttonclicked.dayreport

     > **Info:** The names of the reports must use a specific format:
     >
     > - .hourreport
     > - .dayreport
     > - .weekreport
     > - .monthreport
     > - .yearreport
     >
     > In this example, the code name of the custom statistic is **buttonclicked**, as defined above in the controller code.

5. Click **Save**.

6. Switch to the **Parameters** tab of the new report and use the **New field** button to create three essential parameters, which the web analytics use internally:

   - **Field name:** FromDate

   - **Data type**: Date and Time

   - **Display field in the editing form**: no (cleared)

     > **Note:** Click **Save** for every parameter before moving on to the next one.

   - **Field name**: ToDate

   - **Data type**: Date and Time

   - **Display field in the editing form**: no (cleared)

     > **Info:** The _FromDate_ and _ToDate_ parameters above define a time interval used to limit which data of the statistic is loaded. Only hits that occurred during the specified interval will be displayed in the report. The values of these parameters can be set by users when viewing the data of the statistic in the web analytics interface.

   - **Field name**: CodeName

   - **Data type**: Text

   - **Size**: 20

   - **Default value**: buttonclicked (the code name of the displayed statistic in general)

   - **Display field in the editing form**: no (cleared)

     > **Info:** The system uses the _CodeName_ parameter to identify from which statistic the report loads data. The value is usually not modified if the report is dedicated to a single statistic (like the one in this example).

7. Go to the **General** tab and click **New** in the **Tables** section below the layout editor. Fill in the table's properties as shown below:

   - **Display name**: Table
   - **Code name**: Table\_ButtonClicked\_Day
   - **Query**:

     ```sql

     SET @FromDate = dbo.Func_Analytics_DateTrim(@FromDate,'day');
     SET @ToDate = dbo.Func_Analytics_EndDateTrim(@ToDate,'day');

     SELECT StatisticsObjectName as 'Authentication status', SUM(HitsCount) as 'Hits'
     FROM Analytics_Statistics, Analytics_DayHits
     WHERE (StatisticsSiteID = @CMSContextCurrentSiteID)
     AND (StatisticsCode = @CodeName)
     AND (StatisticsID = HitsStatisticsID)
     AND (HitsStartTime >= @FromDate)
     AND (HitsEndTime <= @ToDate)
     GROUP BY StatisticsObjectName
     ORDER BY SUM(HitsCount) DESC

     ```

     > **Info:** The new report is a daily report, so the data of the table is retrieved from the _Analytics\_DayHits_ table, together with the _Analytics\_Statistics_ table. See [Web analytics API](https://docs.kentico.com/13/on-line-marketing-features/configuring-and-customizing-your-on-line-marketing-features/configuring-web-analytics/web-analytics-api.md) for more information about the database table structure.

     > **Note:** **Trimming the values of the FromDate and ToDate parameters**
     >
     > The SET statements included in the query are necessary to ensure that the specified time interval includes the first and last units of time (e.g. the exact days entered into the **From** and **To** fields of a daily report).
     >
     > The second parameter of the trimming functions must match the time unit of the given report. The options are: _'hour'_, _'day'_, _'week'_, _'month'_, _'year'_.

8. Click **Save & Close** to create the table.

9. Click **Insert** in the **Tables** section to add the new table into the report.

10. Click **Save**.

The daily report is now complete. In a real‑world scenario, the report would usually also contain a graph to display the data. See the [Working with system reports](https://docs.kentico.com/13/configuring-xperience/working-with-system-reports.md) chapter to learn more about graphs and other reporting options.

You can create the reports for the remaining time intervals using the same approach. The only differences should be in the names of the reports and tables, and the code of the queries, where you need to load data from the appropriate tables – _Analytics\_YearHits_ in the yearly report, _Analytics\_MonthHits_ in the monthly report, etc. You can make this process easier by using the **Clone report** () button in the menu above the report tree. Simply create copies of the daily report and then make the necessary adjustments.

### Setting the title for custom statistics

To ensure that the administration interface displays an appropriate title for your custom statistic, you need to create a [resource string](https://docs.kentico.com/13/multilingual-websites/setting-up-a-multilingual-user-interface/working-with-resource-strings.md):

1. Open the **Localization** application.
2. Click **New string** on the **Resource strings** tab.
3. Enter the **Key** of the string in format: _**analytics\_codename.**_ (_analytics\_codename.buttonclicked_ for this example)
4. Type the text of the string for your system's default culture, for example: _Button clicks_
   - If you are using a multilingual UI, you can enter translations of the string for individual cultures.
5. Click **Save**.

The system uses the string as the title for the matching statistic.

### Result

Once there are some hits logged in the database for a custom statistic, the system automatically displays the statistic under the **Custom** category of the tree in the **Web analytics** application. The reports of the sample statistic show the number of hits logged for the tracked button click event.

![Viewing the data of a custom statistic in the Web analytics application](https://docs.kentico.com/docsassets/13/adding-custom-web-analytics/Custom_WA_Result.png "Viewing the data of a custom statistic in the Web analytics application")
