HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Track and recommend

Describes how tracking and recommendations work in Optimizely Product Recommendations.

Track the user journey

Tracking provides personalized recommendations by following the user journey and storing session and user behaviors. This, in turn, enriches the machine learning (ML) algorithms to track key performance indicators (KPI). With Commerce Connect-native integration, a JSON payload is sent to an API endpoint on the Personalization servers that contain information about the page, such as page type, URL, product codes, and so on.

Optimizely recommends tracking all points of the user journey to ensure wide coverage in behavior to be used by ML algorithms. If you cannot do this, you should track product, basket, and order pages—and any other pages that should show recommendations—as a minimum requirement. See Product tracking on World for a list of supported page types.

Personalization relies on user tracking to maintain a cross-platform experience. Yo should track the user email or pseudonym-ized ID at key points in the user journey such as logging in, the checkout process, or any other point of capturing the user ID in line with business requirements.

❗️

Warning

You should ensure that each product refCode is consistent across the site. This is especially important when checking whether the refCode from product page matches the basket, checkout, and order pages because this lets the Personalization system link viewing and buying behavior to a specific product. A mismatch in refCodes can lead to inaccurate reporting and even have a negative impact on behavior.

Control tracking of user IP address 

By default, tracking data sent to the Personalization service includes the user’s IP address. The IP address is not stored in the personalization service—it is only used in the session for geolocation purposes, to improve recommendation accuracy.

You can exclude the IP address from tracking data by using episerver:personalization.SkipUserHostTracking. See Installing and configuring the native integration package.

Alternatively, you can include/exclude IP address by registering a custom implementation of the IRequestTrackingDataServiceinterface (namespace EPiServer.Tracking.Commerce). The default implementation of this interface uses the setting mentioned above, but a custom implementation could vary the setting based on user preference, cookies, and so on.

Control tracking of user’s email address

By default, tracking data sent to the Personalization service includes the user’s email address. You can exclude email address from tracking data by using episerver:personalization.UsePseudonymousUserId. See Installing and configuring the native integration package.

Alternatively, you can include/exclude user email address by registering a custom implementation of the IUserIdentityServiceinterface (namespace EPiServer.Personalization.Common).  If you plan to switch from email to a pseudonymous user identifier (by config or customization), you must synchronize with the personalization service team for any site with existing tracking data. Otherwise, existing tracking data and the profiles built from it are lost when the user identifier changes. See Migrating Server-to-Server API version 1.3 to 1.4.

Product recommendation tracking

Tracking is used for different purposes, for example to provide personalized product recommendations on an e-commerce site. Tracking visitor activities and retrieving recommendations are performed simultaneously in a single round trip to the Optimizely Product Recommendations environment. This round trip is made synchronously and adds a small processing overhead to all tracked requests.

The following diagram describes the flow for page requests that end up in a controller action decorated with a CommerceTrackingAttribute. The flow is identical for tracking requests not triggered by the CommerceTrackingAttribute except the custom tracking code replaces the OnActionExecuting step.

To provide good recommendations, Optimizely Product Recommendations tracks a visitor's activities over time. Product Recommendations accomplishes this by assigning visitors a consolidated user ID (CUID), which is stored in a cookie. User activities that can be tracked are contained in the TrackingType enum. Track as many activities as possible - more tracked activities result in better recommendations.

Tracking here is sent to the Optimizely product recommendation service, but any source can consume tracking of Optimizely Commerce Connect data.

See Product tracking for details about tracking types and attributes for products, and how to install the core tracking.

Customize tracking data

You can include custom tracking data in a tracking request by using the SetCustomAttribute extension method for CommerceTrackingData. Supported data types are limited to common numeric types, string, and DateTime.

A use case for custom tracking attributes is to configure recommendation widgets in the personalization service to filter recommendations based on a known customer preference or other data. For example, a website for browsing or preordering duty free goods for an airport/airline, where available products depend on flight type.

Troubleshoot tracking

Prerequisites

  • At least one successful feed import in the environment being tested (UAT or Production).
  • Tracking was enabled for the specified environment. If this is the case, the epi_RecommendationsTrackingUserId and epi_RecommendationsTrackingSessionId cookies should be available in your browser.
  • You have access to the Personalization Portal for the environment being tested.

The following issues may occur when you implement tracking. See also Personalization in Optimizely Commerce Connect for information about solving issues with tracking integration. If there are additional requirements for tracking, or a problem persists, contact your Product Manager or Optimizely Support.

  • Some page views are missing in the history of tracking requests
    If a page loads on your site and does not trigger a tracking request, tracking could be not implemented for that page type. If you implemented tracking, check other pages of the same type to see whether they are tracking. If not, check other page types, and failing this, refresh the Session Viewer page.

  • Multiple requests are showing for a single page view
    A single page view on your site should be associated with a single tracking request in Session Viewer. Multiple tracking requests can lead to unnecessary processing from the Personalization service and may also cause conflicts when rendering recommendations. Ensure that any calls to internal or external APIs (such as calls to construct widget HTML) do not trigger methods to create tracking.

  • Product page requests have placeholder or no title in the request name or Track Info tab
    The refCode that was passed in the tracking request is not associated with any product in any previous feeds exported for this environment. The refCode should match the root product in the Commerce Connect catalog and the GUID tag in the feed export. The following images show an order placed with placeholder products.

  • I have just viewed a category page, but the request shows the page type is other
    The category that was passed in the JSON payload does not match any categories passed in past feed exports. You can cross-check the category passed in the JSON payload with the tracking information of a product that should be included within this category; either the category being passed in tracking is incorrect, or the categories provided in the feed export are incorrect. Placeholder categories do not exist within Personalization, so tracking defaults to other page type to prevent failing the request.

Consume recommendations

Optimizely defines the following page types as pre-defined tracking types: Home, Search, Category, Product, Basket, Checkout, Order, Wishlist, Brand, and Attribute. If you need recommendations on a page type outside of this set, contact Optimizely to receive further setup instructions.

Optimizely supports additional, real-time filtering based on custom information provided on a per-page level so that you can accommodate business rules, such as only showing product X if the user has permission to view or buy that product. Coordinate custom requirements your Optimizely contact.

Depending on how the Optimizely Product Recommendations environment is configured, different types of tracking events may or may not return recommendations. This section explains a general case where recommendations are returned and should be displayed to the visitor.

Use the CommerceTrackingAttribute

As the CommerceTrackingAttribute executes code in the OnActionExecuting method, the recommendations are available as soon as the controller action method is entered. To get recommendations, call the Controller extension method GetRecommendationGroups.

[CommerceTracking(TrackingType.Home)]
    public ViewResult Index(StartPage currentPage)
      {
        var recommendations = this.GetRecommendationGroups(); 
        ... 
      }

The method returns a collection of Recommendation objects, where each object has an Area and a collection of ContentReferences referencing the recommended products. The Recommendation object can be used to create model data to display recommended products to a site visitor.

The number of Recommendation objects and the names of the areas depend on how the Optimizely Product Recommendations environment is configured. The name for these recommendation groupings on the Optimizely Product Recommendations side is widgets. A widget contains information about where recommendations should appear on a page (left, right, bottom, and so on) and which algorithms are used to generate recommendations, such as similar products and cross sells.

var productRefs = widgetService.UpdateWidget().Where(x => x.Area == "someWidget").SelectMany(x => x.RecommendedItems);

Without using the CommerceTrackingAttribute

Working with the recommendations returned from the ITrackingService.Track extension method is similar to working with the attribute. A GetRecommendationGroups extension method exists for the returned tracking response data and works the same way as with the controller.

Link visitor actions with recommendations

Valuable business intelligence is based on knowing which recommended content a visitor acts upon.

As of version 2.1.0, TrackingMode is obsolete. Also, Js tracking APIs and server tracking APIs are independent and work in parallel.

Js tracking APIs support setting RecommendationId for ProductTrackingData, which is read from the TrackingProxy and sent to the Product Recommendations Engine. So, if you use JS API tracking, you do not need to use cookies or RecommendationContext. Further, Commerce Connect reference sites have changed the way they store RecommendationId values. Now, they use a Query String by adding a new RecommendationId parameter in the data-url attribute of the Shares\_RecommendationsTemplates.cshtm template.

Commerce Connect reference sites no longer use RecommendationContext. See also: Client-side API integration.

<button type="button"
            data-toggle="modal"
            data-target="#ModalDialog"
            data-url="{{#attributes}}{{url}}{{/attributes}}&recommendationId={{id}}"
            class="btn btn-block btn-sm quickview-button">
      @Html.Translate("/Product/Quickview")
    </button>

When a user clicks Recommendation products, the Commerce Connect reference site redirects to the Product Detail page with the RecommendationId value passed in as a QueryString. Then, the JS  TrackingDataFactory.createProductTrackingData API gets the RecommendationId value from QueryString and creates tracking data to send to the Tracking Proxy.

<script>
      $(document).ready(function ()
        {
          var refCode = '@Model.Product.Code';
          var productName = '@Model.Product.Name';
          var productTrackingData = TrackingDataFactory.createProductTrackingData(refCode, productName);
          productTrackingData["SkipRecommendations"] = true;
          var recommendationId =  parseInt(isNaN('@Request.QueryString["recommendationId"]')? '0': '@Request.QueryString["recommendationId"]');
          if (recommendationId > 0) 
            {
              productTrackingData["recommendationId"] = recommendationId;
            }
          productTrackingData["customAttributes"] = { 'marketId': Market.getSelectedMarketId() };
          epiRecommendations.track(productTrackingData);
        });
    </script>

The following image describes this process.

Verify click-tracking

You should render recommendations on site, but also track them correctly for the system to attribute user interactions with recommendations and to generate accurate reports. Click-tracking is the basis for key metrics to track recommendation performance, such as <madcap:glossaryterm glossterm="Glossary-EPiServer.Term138">click-through</madcap:glossaryterm> rate, click-to-purchase, and so on. If click-tracking is incorrectly implemented, reports in the Personalization Portal will show no Optimizely-generated revenue. See Linking visitor actions with recommendations for more detail.

To verify click-tracking is implemented correctly, you will need to:

  • View a page with recommendations enabled, and click a recommendation.

  • In the tracking response that originally generated the recommendation, find the recommendation ID for the recommendation. This is the ID value in the JSON response. (Alternatively, open the Response tab, expand the fields to find the ID of the recommendation clicked. The following image shows the Rec viewed Id is the ID that should be marked as clicked.

  • For native and server-to-server integrations, check that the click ID logged in the subsequent request and response matches the recommendation ID from the previous step. The following image shows the request with "info":{"smartRecs":{"click":60088462}}.

    The following image shows the response, the click is logged as "info":{"smartRecs":[{"click":”ok”,”id”:60088462}]}.

  • For JavaScript API integrations, place breakpoints in the smartRecsClick and smartRecsSendClick functions in the peerius.page script and ensure the ID passed to the function matches the ID from the smartRecs response.

Troubleshoot Recommendations

Prerequisites

  • At least one successful feed import in the tested environment (UAT or Production).
  • Tracking was enabled for the specified environment. If this is the case, the epi_RecommendationsTrackingUserId and epi_RecommendationsTrackingSessionId cookies should be available in your browser.
  • You have access to the Personalization Portal for the environment being tested.
  • See Administer the Personalization Portal for information about the Session viewer.

The following issues may occur when you implement Recommendations.

  • Metrics such as click-through rate (CTR), click-to-purchase (CTP), and Optimizely-generated revenue are showing as 0 in the portal
    This can be caused by product refCode being inconsistent between the product page and order page, or click-tracking is incorrectly implemented. If the issue persists, contact Optimizely for assistance.

  • Recommendations are not being returned
    There are several reasons this may happen, but you can analyze the JSON response to help find a root cause. The response payload is at Console > Response > JSON.

    When the response JSON contains the smartRecs object with an empty array as the value [], recommendations are disabled in the request using the "smartProducts" : [] flag. If recommendations should be returned in this instance, (for native integrations check that CommerceTrackingData.SkipRecommendations() is not being called before passing it to the TrackingService and for JavaScript integrations), consult with Optimizely for more details.

    {
           "session"        : {
                                "session" : "122289928212|jVsQ4-z8Shoq9p-Ufs905rzXtsfq6984fkbdEnfokEY",
                                "cuid"    : "76872594962|oLDX68UmK-zsvRYWWsXkND1W3Nofo9fFILiCv4KvwpQ"
                              },
           "pageTrackingId" : "876615918262|uAjKdc4kr1KBRwwSiK1_Rw",
           "smartRecs"      : [],
           "status"         : "OK"
         }
    

    When the response JSON does not contain the smartRecs object, there are no widgets enabled for that page type within Personalization. If there should be a widget returned for the page type being checked, consult with your Optimizely contact for more details.

    {
           "session"        : {
                                "session" : "122289928212|jVsQ4-z8Shoq9p-Ufs905rzXtsfq6984fkbdEnfokEY",
                                "cuid"    : "76872594962|oLDX68UmK-zsvRYWWsXkND1W3Nofo9fFILiCv4KvwpQ"
                              },
           "pageTrackingId" : "876615918262|uAjKdc4kr1KBRwwSiK1_Rw",
           "status"         : "OK"
         }
    

    The following response shows the smartRecs array has a single widget for this page type. However, the recs object is returning an empty array. To debug this, do the following:

    • Check that the lang in the tracking request matches a location in the latest feed export where multiple locales are being used. If you are unsure of which locales your site uses, contact Optimizely.
    • Ensure that all products in the latest feed export have a stock level greater than 0 and are set as recommendable.
    • If there are any merchandising campaigns set up in the portal for the page, make sure that the feed export contains the required attributes and categories. Merchandising campaigns are at Configuration > Product Recommendations > Campaigns in the Personalization Portal.
    {
               "session"        : {
                                    "session" : "122289928212|jVsQ4-z8Shoq9p-Ufs905rzXtsfq6984fkbdEnfokEY",
                                    "cuid"    : "76872594962|oLDX68UmK-zsvRYWWsXkND1W3Nofo9fFILiCv4KvwpQ"
                                  },
               "pageTrackingId" : "876615918262|uAjKdc4kr1KBRwwSiK1_Rw",
               "smartRecs"      : [
                                    {
                                      "widget"   : "homeWidget",
                                      "alias"    : "",
                                      "position" : "homeWidget",
                                      "recs"     : []
                                    }
                                  ],
               "status"         : "OK"
             }
    
    • If these steps do not solve the issue, contact Optimizely for further support.
  • Widgets were returned before a deployment but now some are missing
    For native integrations, in cases where you have custom widgets set up outside the default set of 6 widgets enabled on home, category, search, product, and basket pages, it is possible that re-activating widgets within your instance will reset the Personalization configuration to the default set of widgets enabled per page. See Activating widgets.

    You should activate widgets once per environment. If custom widgets are not returned, contact Optimizely for support.

    For JavaScript API integrations, check that tracking is in place where you expect recommendations and verify that recommendations are being returned through the PeeriusCallbacks.smartRecs callback function. If recommendations are returned, the issue may lie in the client-side rendering, otherwise contact Optimizely for support.

Output caching

If you want to use output caching for pages that show recommendations, you must use the client side tracking API in version 2.1.0 (or later) of the EPiServer.Personalization.Commerce package.

Caching of content is controlled by the "httpCache"-prefixed settings of the applicationSettings element and usage of the ContentOutputCache attribute. Note that caching enabled by these settings does not apply to authenticated users. Output caching breaks the server-side tracking, because the request most often does not reach the page's controller - users will see the cached recommendations, and user behavior will not be tracked.