FXM on Single Page Applications

Pushing route visits

I had a usecase where I needed to use FXM in a non-Sitecore Single Page Application. By default, FXM only supports loading its script on page load to push a page visit to Sitecore. However, for an SPA this is not very helpful since after the initial load of the APP it only changes routes and will not push events to FXM.
So to support pushing route visits from the SPA to Sitecore analytics I made some slight modifications to the standard FXM beacon script to enable the SPA to push a visit to a route to Sitecore. Of course within the SPA this needs to be supported, so the default beacon script needs to be loaded and below PushRouteEvent method called on each route visit.

function PushRouteEvent(){
        var xmlhttp = new XMLHttpRequest();

        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == XMLHttpRequest.DONE) {
                if (xmlhttp.status == 200) {
                   document.getElementById("myDiv").innerHTML = JSON.parse(xmlhttp.responseText).ElementMatches[0].RenderedContent;
                }
                else if (xmlhttp.status == 400) {
                    alert('There was an error 400');
                }
                else {
                    alert('something else other than 200 was returned');
                }
            }
        };

 var host = "yoursitecore.domain";
 var beaconTrackPageVisitLocation = "/sitecore/api/ssc/Beacon/Service/beacon/trackPageVisit/?";
 var contactId = "contactId=" + htmlEscape(getCookie('sc_ext_contact'));
 var sessionId = "&sessionId=" + htmlEscape(getCookie('sc_ext_session'));
 var route = "&page=" + htmlEscape(window.location.href);
 var referrer = "&referrer=" + htmlEscape(document.referrer);
 var time = "&rt=" + Date.now();
 var url = host + beaconTrackPageVisitLocation + contactId + sessionId + route + referrer + time;
 xmlhttp.open("POST", url, true);
 xmlhttp.send();
}
function getCookie(name) {
 var re = new RegExp(name + "=([^;]+)");
 var value = re.exec(document.cookie);
 return (value != null) ? unescape(value[1]) : null;
}

function htmlEscape(str) {
 return str
  .replace(/&/g, '&')
  .replace(/"/g, '"')
  .replace(/'/g, ''')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;');
}


Note that this code was tested on Sitecore 8.2 update 5, if FXM changes its endpoints, beacon script or signature this might break

This script used the Sitecore cookies that FXM beacon brings to your external site to determine the visitor's contact Id and session Id and uses it to push the visit event.

Displaying content blocks

Next to measuring events, there was also a need to embed Sitecore content in the SPA solution. To support this in above script you can see that from the response of the PageVisit api call content can be retrieved that has been placed on the site using FXM.
In the FXM interface, you can open your FXM site in the experience editor and add content in a placeholder for your site. This placeholder can be inserted anywhere in your app and in the SPA setup, it won't actually be inserted by Sitecore, but we will retrieve the content from the Beacon api and insert it at desired location ourselves as shown in above script.


 
   "ContactId":"b6e332ab125647228a7e9eca4913db04|True",
   "SessionId":"0rcuupinrxqis2cbqqkrsg3e",
   "ContactExpires":"2019-12-12T21:24:51.3373755",
   "SessionPath":"/",
   "ElementMatches": 
       
         "RenderedContent":"<form method=\"post\" action=\"/sitecore/api/ssc/Beacon/Service/beacon/trackPageVisit/?contactId=b6e332ab125647228a7e9eca4913db04|True&amp;sessionId=0rcuupinrxqis2cbqqkrsg3e&amp;page=http://myfxm/&amp;referrer=&amp;rt=1513106691296\" id=\"ctl00\">\r\n<div class=\"aspNetHidden\">\r\n<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"vv4ddlIG5wTFrM73KnJooTeqUS5pR4Kbbkr/s+cFzrlMnLEBQvYxpgDCMWn6KLCNpttUwvEtQEDFw454OX/gZS/JULUKWdqkOzqWdIUdVD7AX8nu+XLSHVJ9SevFTCf1\" />\r\n</div>\r\n<div><h1 class=\"contentTitle\">Sitecore Experience Platform</h1><div class=\"contentDescription\"><p style=\"line-height: 22px;\">From a single connected platform that also integrates with other customer-facing platforms, to a single view of the customer in a big data marketing repository, to completely eliminating much of the complexity that has previously held marketers back, the latest version of Sitecore makes customer experience highly achievable. Learn how the latest version of Sitecore gives marketers the complete data, integrated tools, and automation capabilities to engage customers throughout an iterative lifecycle &ndash; the technology foundation absolutely necessary to win customers for life.</p>\r\n<p>For further information, please go to the <a href=\"https://doc.sitecore.net/\" target=\"_blank\" title=\"Sitecore Documentation site\">Sitecore Documentation site</a></p></div></div>\r\n<div class=\"aspNetHidden\">\r\n\r\n\t<input type=\"hidden\" name=\"__VIEWSTATEGENERATOR\" id=\"__VIEWSTATEGENERATOR\" value=\"B82EF22B\" />\r\n</div></form>",
         "RenderedPosition":"{18F0F47F-2214-4F23-B6FA-F2D86A0C9E5A}",
         "Selector":"body > div:not([sc-part-of]):eq(0) > h1",
         "MatchType":"content",
         "Id":"{65A14045-4483-49FF-96A4-0AF3979893F8}"
      },
       
         "RenderedContent":"<div><h1 class=\"contentTitle\"></h1><div class=\"contentDescription\"></div></div>",
         "RenderedPosition":"{FDBF46B4-5B52-4C7A-A254-B588EC52944E}",
         "Selector":"#myDiv > p",
         "MatchType":"content",
         "Id":"{F1B44BE8-401E-47C2-BD2A-0B9505FA6399}"
      }
   ],
   "Id":null,
   "Url":null
}

Above call will return above body as a response. As you can see the returned object is a JSON containing content to be served. Your SPA can pickup this content and render it in therefore designated content area's.

Although all this isn't the prettiest code, it shows that it is very well possible to use FXM in a Single Page Application, track navigation through the app and serve content in area's the SPA developer wants to put it in. This does require support from the SPA developer though, more then just inserting the FXM script, but also dealing with this additional javascript to do the tracking and inserting the data. It is however a very small effort.

Reacties

Populaire posts van deze blog

I Robot - Sitecore JSS visitor identification

Sitecore campaigns and UTM tracking unified

Sitecore JSS - Sitecore first