Sitecore xDB - Capturing Contact Data from non-Sitecore Site - Part 3 - Capture Contact Data

This is part 3 of my blog series on how to capture contact data from a non-Sitecore site and import into Sitecore xDB.

In this blog I will go over how to actually capture contact data from any non-Sitecore site as long as the site has been added to FXM.


There are couple of different ways to capture contact data and I am going to go over one of the ways in this blog. The implementation I am going to walkthrough can be used to capture contact data independently from Sitecore. There are 3 main components:

  1. SQL database to store captured contact data
  2. xDB Contact Capture service
  3. Javascript file that will be referenced in non-Sitecore site (the same way beacon for FXM is referenced)

The overall architecture of this part is shown in the diagram below.

SQL Database

You can generate SQL database from the DbModel in the xDBCC.Services.ContactCapture project. Database only has one table Contacts.

xDB Contact Capture Service

We will capture contact data through referenced javascript files and post to this service. To install this service locally folow these steps:

  1. in wwwroot folder create a new folder xdbcc.services.contactcapture
  2. in IIS create a new site with these settings

  3. Add xdbcc.services.contactcapture to hosts file
  4. Publish xDBCC.Services.ContactCapture project

Javascript files

There are 2 javascript files that need to be referenced on the non-Sitecore site where we want to capture the data.

These are the 2 js file that need to be referenced.


This file is collecting contact data and saving it to a session cookie for later.

$(function () {

    // Using sc_ext_contact instead of SC_ANALYTICS_GLOBAL_COOKIE for non-Sitecore site
    // because sc_ext_contact is using the correct domain. Script will not be able to access
    // SC_ANALYTICS_GLOBAL_COOKIE since it has domain from Sitecore instance.
    // In my example:
    // SC_ANALYTICS_GLOBAL_COOKIE   = .xdbcontactcapture.local  -> this is sitecore instance domain and script cannot access it
    // sc_ext_contact               = xdbcc.sites.nonsitecore   -> this is the domain of the non-Sitecore site and script can access it
    var scContactCookie = Cookies.get('sc_ext_contact');

    if (scContactCookie != undefined) {
        // sc_ext_cookie will look something like this "66bd94a5a8c84f5d9ac44e587dfd280d|False"
        // get the first part of the "|" delimited string
        var contactId = scContactCookie.split("|")[0];

        // output contactId in console for debugging purposes
        console.log('contactId -> ' + contactId);

        // attach click event for the submit button (or any other button you wish depending on the site)
        $("#submit-button").click(function () {

            // get all the data we need from the page into JSON object
            var contactInfo = {
                ContactId: contactId,
                FirstName: $('#FirstName').val(),
                LastName: $('#LastName').val(),
                Email: $('#Email').val(),
                Country: $('#Country').val(),
                PostalCode: $('#PostalCode').val()

            // now, let's stringify JSON object
            var jsonData = JSON.stringify(contactInfo);

            // save serialized contact data to a session cookie to be accessed later
            Cookies.set('ccs-contact', jsonData);


This file is retrieving saved contact data and posting it to xDB Contact Capture service.

$(function () {
    // sample service uri to post the contact data to
    var xPostUrl = "//xdbcc.services.contactcapture/api/data";

    // get session cookie with stringified contact data saved earlier
    var ccsContactCookie = Cookies.get('ccs-contact');

    // if can't find the session cookie do nothing
    if (ccsContactCookie != undefined) {
        // everything is looking good so far, go ahed and post to service
            type: "POST",
            url: xPostUrl,
            data: { "": ccsContactCookie },
            crossDomain: true,
            beforeSend: function (data, settings) {
                console.log('POST -> beforeSend: ' + ccsContactCookie);
            success: function (data, textStatus, jqXHR) {
                console.log('POST -> success: ' + data);
            error: function (data, textStatus, errorThrown) {
                console.log('POST -> error: ' + data + " | errorThrown: " + errorThrown)

Steps on how to actually capture contact data

Step 1

Identify a page where needed user data is rendered or where user will have to enter some data. In my example I added contacts-capture-collect.js file to the page where user is filling out some information and capture that data when Submit button is clicked.

Here is the referenced js file that is added on the Form page (I am using js.cookie.min.js plugin so that file is referenced as well. This may or may not be needed depending on what is already there on a specific non-Sitecore site)

<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
    <script src="//xdbcc.services.contactcapture/scripts/contacts-capture-collect.js"></script>

 Step 2

Once user clicks on Submit button he or she is then redirected to the Confirmation page. This is where we add the reference to the 2nd javascript file, the one that actually posts the data to the xDB Contact Capture service.

<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.0/js.cookie.min.js"></script>
    <script src="//xdbcc.services.contactcapture/scripts/contacts-capture-post.js"></script>


All code is available in my GitHub repository.


So, we setup xDB Contact Capture service to post data to, update and reference files in non-Sitecore site(s) and generate SQL database to store all contact data into. That pretty much sums it up.

In the next blog I'll go over how to import captured contact data into Sitecore xDB.

This is a personal blog. The opinions expressed here represent my own and not those of people, institutions or organizations that the owner may or may not be associated with in professional or personal capacity, unless explicitly stated.. In addition, my thoughts and opinions change from time to time I consider this a necessary consequence of having an open mind. This blog disclaimer is subject to change at anytime without notifications.