Track User's In-store Experience with Episerver Profile Store


Quick Summary

In March of 2018, Episerver hosted its annual Ascend conference in Las Vegas. This year they ran a Partner Innovation Spotlight, where they asked all of their partners to come up with some new and innovative ways to use their products. At Making Waves, we wanted to bridge the gap between the online and in-store experience.

To do this, we simulated a shoe store experience that tracked user’s behavior using a mixture of a mobile app, Bluetooth beacons, and Episerver Profile Store. We were able to connect these technologies through our Track API.

While this blog is focusing on the technical aspects of the Track API, I encourage you to check out this post from our Delivery Director Arnold Macauley that walks through why we chose to go this route for our demo.

Shoe Demo Display

Episerver Profile Store & Insight

This post assumes you are familiar with the Episerver’s Profile Store & Insight. If not, I would recommend familiarizing yourself by looking at the developer documentation for the Profile Store & Insight.

If you skimmed right past those links because you saw “documentation” and thought to yourself, “no way,” Episerver provides a good summary right at the top of each page:

Episerver Profile Store tracks and saves data about the behavior of a website visitor each time a visitor views a product, adds a product to wish list or shopping cart, placed an order and so on. You can use actual, timely data to provide a site visitor with a custom experience.

Episerver Insight is the user interface for viewing and filtering visitor profiles, and creating segments to be used as input for omnichannel campaigns.

Since this post is more focused on the technical end, we will be focusing more on the Profile Store. However, in order to view the profiles, we are creating and tracking we need to view them through Insight. So its good to familiarize yourself with both.

In-Store Experience

We used Bluetooth beacons to track interactions with individual products. Based on which product was handled and for how long, we would provide users with prompts for suggested products and options to purchase. Gestures were used to track as uses enter and exit the store.

The Android app would then send these interactions to the Track API, which stores the information in the Profile Store.

Track API

As I mentioned previously, the Track API was used to track user’s in store behavior. While you can view the full implementation of the API in this gist of the TrackController, in this post we are going to focus on just one method.

One thing to note is that the user that we are tracking is signed in to the site through the Android app. Because of this, we are able to get the user from the requests that are made to our API.


The TrackProductView method takes as a parameter a string of the beacon ID and is used to track whenever a user interacts with a product.

    public async Task<IHttpActionResult> TrackProductView(string beaconId)
        var user = GetUser();
        string code = GetCode(beaconId);

        if (string.IsNullOrWhiteSpace(code))
            return NotFound();

        var contentLink = _referenceConverter.GetContentLink(code);

        var productName = code;
        if (!ContentReference.IsNullOrEmpty(contentLink))
            var product = _contentLoader.Get<EntryContentBase>(contentLink);
            productName = product.Name;

        var trackingData = new TrackingData<ProductTrackingData>
            EventType = CustomTrackingType.Store,
            EventTime = DateTime.UtcNow,
            User = user,
            Value = $"Viewed {productName} in the Las Vegas store.",
            Payload = new ProductTrackingData(code, "en", _httpContextBase, GetCommerceUser()),
            PageTitle = productName,

        await _trackingService.Track(trackingData, _httpContextBase);

        return Ok(trackingData.Value);

The first thing we do in this method is getting the user from the request. Next, we use a JSON mapping of beacon IDs and product codes to get the code of the product the user is interacting with. We use an editable property on the start page to store the JSON mapping. This gives us the ability to quickly and easily update if a new product is introduced or if one of the beacons needs to be replaced.

From there, using an instance of ReferenceConverter, we are able to get the ContentLink of the product. In turn, we can use an instance of IContentLoader to get the product.

Finally, the most important part of the method is where we call the Track API to save the product view to the profile store. We create a new instance of TrackingData which has a Payload of type ProductTrackingData. We specify that the EventType is “store” to let us know it was viewed in the physical store instead of the site. Payload is an instance of ProductTrackingData, where we provide the product code, language code, current HttpContext, and the current user. Then we call Track from an instance of ITrackingService that we injected into our Controller. You can see the results store in Insight below.

Insight View-min


As you can probably tell, the ability to connect the in-store experience with online profiles is pretty powerful. You can see from the view of the Insight Profile panel, we are able to see every step of the customer’s journey. From coming to our site and creating an account, to entering the store, viewing products, and purchasing. Our demo focuses on beacons and gestures. However, this controller can be expanded to tracking things such as NFC tags, GPS, and even QR codes.

We will be coming out with more posts about our store demo, but I encourage you to read the post I mentioned above. Also, check out the video below that shows our store experience in action.