How to integrate X into your website

Overview

This guide is designed to help you integrate your X instance autonomously once it has been fully instrumented.

It provides detail on all the aspects of the integration, including initialization, accepted configurations, analytics and custom code hooking.

Table of contents

Step-by-step guide

Integrating X into your website is a straightforward process that consists of two steps:

  1. Loading the X JavaScript resource

  2. Initializing X

Loading the X JavaScript resource

The first step for integrating X is loading the X JavaScript resource.

This resource contains a webpack bundle with all the logic, templates, styles and dependencies.

X resources are served by a CDN through the following URLs:

LIVEhttps://assets.empathybroker.com/empathyx/{INSTANCE}/app.js
STAGINGhttps://preassets.empathybroker.com/empathyx/{INSTANCE}/app.js

Where {INSTANCE} is a unique identifier provided by EmpathyBroker.

Please note that X and Search are totally independent, which means that staging resources for X will still consume production endpoints by default. We will see how to switch API endpoints later on.

The recommended way to load the X JavaScript resource is by using the following tag in your HTML structure:

<script defer src="https://assets.empathybroker.com/empathyx/{INSTANCE}/app.js"></script>

The defer attribute help to keep it blazing fast by loading the resource asynchronously and without blocking the page load. Once the script is ready, X will automatically call the global initEmpathyX function (see the Initializing X section).

Initializing X

The second step for integrating X is setting up the initEmpathyX callback function. Having a callback function allows X to be loaded and initialized asynchronously.

Inside of the initEmpathyX function, the global EmpathyX object is already available and X is ready to be initialized. To do that, you can use the init function:

function initEmpathyX() {
  EmpathyX.init({
    instance: '{API_INSTANCE}',
    lang: 'en',
    scope: 'mobile',
    currency: 'EUR',
    consent: false
  });
}

Please note that the initEmpathyX function should be defined and available by the time the X resource finishes loading. Also, it is not recommended to call this function manually.

Both the script and the initialization snippet must be present in the HTML of all pages where search is available.

Dynamic configurations

As you can see in the example above, the init function receives a configuration object. This object contains all the dynamic parameters needed by X in runtime.

If you need to change this configuration once X is already initialized, check the Changing the dynamic configuration section.

This is the list of parameters that are currently supported:

ParameterTypeRequiredDefaultDescription
instancestringYes'ebdemo'

Unique identifier of your Search API instance.

consentbooleanYesfalse

This parameter is used to let X know whether the user has accepted the usage of cookies and therefore the user, session and user type cookies can be used and sent to the Search API.

If this parameter is configured with false value, then the cookies will be deleted and removed from all Search API calls.

No consent means results will not be personalized and signals (Related Tags, Next Queries, etc.) will not be inferred from that session.

This parameter should be set to true as soon as the user accepts the usage of EmpathyBroker's cookies.

If accepting the cookies does not trigger a page reload, please consider using the EmpathyX.setConfig function (see the section below) to update the consent parameter so that the current session is tracked already.

scopestringYes'mobile'

The value of this parameter is sent to the Tagging API to be able to segment user sessions by device in analytics and reporting.

The typical values for this field are 'desktop', 'tablet' and 'mobile', but any value is accepted, so pick the ones that best fit your necessities.

Examples:

'desktop'

'tablet'

'mobile'

documentDirection'ltr', 'rtl' No'ltr'This value tells EmpathyX if it should handle the layout in a right to left way or left to right way.
envstringNo

This parameter can be used to switch the Search and Tagging API environment.

Production endpoints are used by default when this parameter is omitted.

To use the STAGING environment, the value for this configuration would be 'staging'.

Examples:

'staging'

langstringNo'en'

Language to be used by X for internationalizing messages (i.e. language of the search interface).

If there are no translations for the specified language, the fallback language ('en') will be used.

Examples:

'es'

'en_UK'

searchLangstringNo'en'

Language to be used by X for Search API requests (i.e. language of all catalog related information, such as results or filters).

By default, if searchLang is omitted, all catalog related information is presented in the language specified in lang.

Please note this parameter should only be used when messages and catalog are in different languages.

Examples:

'es'

'en_UK'

currencystringNo'EUR'

Currency code (ISO 4217) to be used by X for price formatting, both for products and the price filter.

Examples:

'USD'

'CAD'

filtersobjectNo{}

This parameter allows pre-selecting filters even before the user launches the first search.

Pre-selected filters are particularly useful for keeping consistency between navigation and search in those situations where the user is asked to pick an option before starting the journey, such as MAN / WOMAN in fashion or PERSONAL / BUSINESS in services and telecommunications. If this is not required, the usage of pre-selected filters is discouraged.

Please note pre-selected filters behave as radio buttons in the sense that the user can change their values but not de-select them, so use them wisely.

The configured filters must match the names and values in the catalog, which means that values have to be adapted to the selected language (e.g. 'Woman' for English vs 'Mujer' for Spanish).

Examples:

{
  // name: 'value'
  section: 'Woman',
  category: 'Jeans'
}

eventCallbacksobjectNo

The eventCallbacks object is a way to run custom JavaScript code when certain user events happen.

This object accepts a callback function for each of the following events: query, click, add2cart, checkout, filter, clearFilters, sort, columnsChange, resultsEnd, open and close.

Every time one of those events happen, the corresponding callback is executed, sending an object containing all relevant information to that event.

You can check the map of current events and parameters in the data object in the Event callbacks parameters section:

This is useful for situations such as:

  • Integrating with an external analytics platform like Google Analytics (see this section for more details)
  • Fetching asynchronous data in query time from external services
  • Adding a product to the cart when the add to cart button is displayed in the search results page

Examples:

{
  query: function(data) {
    // Send analytics event if the query was not loaded from the URL
    if (data.origin !== 'linked') {
      window.dataLayer.push({...});
    }
  },
  add2cart: function(data) {
    // Add product to the cart if the event was triggered in the search results page
    if (data.context === 'SRP') {
      myAwesomeCart.add(data.productId);
    }
  },

  checkout: function(data) {

    // In this case data is a set of results, ie: { resultId1: resultData1, resultId2: resultData2 }

  }
}

sectionstringNo

Section identifier used by X for the Discovery Wall feature

Not applicable to all instances

storestringNo

Store identifier used by X when querying the Search API.

Not applicable to all instances.

catalogstringNo

Catalog identifier used by X when querying the Search API.

Not applicable to all instances.

warehousestringNo

Warehouse identifier used by X when querying the Search API.

Not applicable to all instances.

Changing the dynamic configuration

There are some situations where the configuration X was initialized with is not valid anymore, for instance when the user changes the language or the currency.

If these actions trigger a page reload on your site, then you are covered: X will initialize again with the correct values. However, if you need to change this configuration on the fly, you can use the EmpathyX.setConfig function.

The EmpathyX.setConfig function receives an object that can contain any of the configurations above. Once executed, it will update the internal configuration and reflect the changes in the interface.

One example of how this function may be used is setting the consent parameter to true as soon as the user accepts the usage of cookies, so that the first session is tracked already:

EmpathyX.setConfig({
  consent: true
});

Event callbacks parameters

This is the list of parameters that are sent in the data object to each callback function in the eventCallbacks object:

ParameterDescription

query, filter, clearFilters, resultsEnd, sort, columnChange, open, close

clickadd2cartcheckout
catalogCatalog identifier provided to X in the snippet.XXXX
context

Page where the add2cart event was triggered.

The possible values for this parameter are:

  • 'SRP': search results page
  • 'PDP': product details page

This parameter is typically used as a discriminator to determine whether to add a product to the cart when the add to cart button is present in the search results page.



X
contextualizeWhether the query has been contextualized.XXXX
filteredWhether the query has been filtered.XXXX
followWhether the user has been redirected to the product page after tracking the event.
XXX
langLanguage identifier provided to X in the snippet.XXXX
origin

Origin of the query that originated the event.

The possible values for this parameter are:

  • 'default'
  • 'empathize_category'
  • 'empathize_term'
  • 'history'
  • 'next_query'
  • 'next_query_grid'
  • 'linked'
  • 'partial'
  • 'related_tag'
  • 'spellcheck'
  • 'no_results'
  • 'empty_search'
  • 'empathize_recommendations'
XXXX
page

Page number where the event was originated.

In case of the query event, it means the page number that was loaded (1 for the initial query; 2, 3, 4... for the subsequent pages as the user scrolls down or paginates).

For product-related events, it means the page number of the result that triggered the event.

XXXX
positionSpecific grid position (starting at 1) of the result that triggered the event.
XXX
productIdUnique identifier of the product in the feed.
XXX
qQuery that originated the event.XXXX
scopeScope provided to X in the snippet.XXXX
sessionUnique identifier of the user session (only present if consent was set to true in the configuration).XXXX
spellcheckWhether spellcheck has been applied to the query.XXXX
storeStore provided to X in the snippet.XXXX
titleName of the result that triggered the event.
XXX
totalHitsNumber of results matching the query.X


urlURL of the result that triggered the event.
XXX
userUnique identifier of the user (only present if consent was set to true in the configuration).XXXX
user_type

User type (only present if consent was set to true in the configuration).

The possible values for this parameter are:

  • 'new'
  • 'recurrent'
XXXX

Integrating X with Google Analytics and other external analytics platforms

So you are going back from product page. Or opening the URL your best friend just shared with you. Or just reloading the page after your laptop ran out of battery. In all those situations, X needs to be able to store and recreate its previous state. And to do so, it uses the URL query string.

In order to make search as fast and interactive as possible, X does not refresh the page when it modifies the query string. Looking at it from an analytics perspective, this means X will not trigger page view events in platforms that depend on page reload (such as Google Analytics).

If that happens, all those valuable search insights will be lost. What can we do then?

Fortunately, this is easy to prevent by using the eventCallbacks object, which gives you a lot of control on how and when you want to track your data:

eventCallbacks: {
  query: function(data) {
    // Filter out queries that were loaded from the URL, such as page reloads 
    // or going back from product page (those are automatically tracked by GA)
    if (data.origin !== 'linked') {
      // Push the page view event manually in any other situation
      window.dataLayer.push({...});
    }
  }
}

In the example above, we can see one of the most typical approaches:

  1. First, we define a custom callback function bound to the query event.
  2. Inside of that function, we perform a basic check to filter out all those situations that trigger a page reload (those are automatically tracked by GA).
  3. Once we have filtered out the undesired query events (which could contain additional checks if necessary), we manually push the page view event.
    • The specific syntax for pushing the event may vary depending on the platform and its implementation.

Identifying a product page and integrating add2Cart and checkout

EmpathyX public API offers ways to identify a page as a product one and facilitates tracking of add2Cart and checkout.

FunctionParameterDescription
productPageproductId: stringThis function must be called after initializing EmpathyX in a product page, passing the current product id as parameter. Please note that the productId must be an existing field in the feed and should be specified beforehand to our team.
add2CartOnProductPageClicked
This function should be hooked into the add2cart's button onclick handler and it doesn't need any parameter.
checkoutproductsIds: string | string[]This function should be hooked into the checkout's button onclick handler. It expects the checkout/baskets product id/list of products ids.

Identifying a product page

In order to allow EmpathyX identify the current page as a product page, our public API has a productPage function that only requires a string parameter (the product id the page belongs to).

Please note that the productId must be an existing field in the feed and should be specified before hands to our team.

EmpathyX initialization + productPage
function initEmpathyX() {
  EmpathyX.init({
    instance: '{API_INSTANCE}',
    lang: 'en',
    scope: 'mobile',
    currency: 'EUR',
    consent: false
  });
  EmpathyX.productPage('{PRODUCT_ID}');
}

Integrating add2Cart

Add2Cart example
// HTML approach
<button class="add2Cart" onclick="EmpathyX.addToCartOnProductPageClicked()"/>

// JS addEventListener approach
<script>
	document.querySelector('{ADD_TO_CART_SELECTOR}').addEventListener('click', function() {
		EmpathyX.addToCartOnProductPageClicked();
	});
</script>

(warning) Notice that add2cart event has to be fired as many times as product is added to cart and related with the quantity of products added to cart. (i.e if quantity == 2, the event has to be fired twice)

Integrating checkout

Checkout example
<script>
document.querySelector('<checkout>').addEventListener('click', function() {
	// Get the product ids from your basket/checkout in any manner (your custom implementation)
	var productsIds = getCheckoutProductsIds();
	EmpathyX.checkout(productsIds);
});
</script>

(warning) Notice that product's quantity has to be considered when creating the productsIds array  (i.e if quantity == 2, the productId has to be added twice to the productsIds array)

Polyfills and browser support

X supports (at least) the following browsers:

BrowserVersion(s)Notes
ChromeLatest 5Includes Chrome for Android
FirefoxLatest 5Includes Firefox for Android
OperaLatest 5Includes Opera Mobile
Safari9+Includes iOS Safari
EdgeAll
Internet Explorer10+
Android Browser4+

To achieve this degree of support while using advanced JS and CSS features, X uses polyfills. Those polyfills are loaded dynamically only when needed, which means users on modern browsers will save those additional KBs.

If you are experiencing any issue with X in any of the above, please file a ticket using EmpathyBroker's Support Platform.

Troubleshooting (FAQs)

I am A/B testing the solution and I need to load X dynamically. What can I do?

In order to load X dynamically, you can just follow the regular process as long as the initEmpathyX function is defined by the time the X resource finishes loading. The initEmpathyX function will still be automatically called in those situations.

This becomes really handy when your A/B testing tool forces you to embed the dynamic code for that branch in the head.

How can I load X synchronously?

Loading X synchronously is not recommended, since it will probably slow your page load.

If you still need to do so, you can remove the async and defer attributes from the script tag and write subsequent script tags assuming that the resource is already loaded.

This will cause the loading of the resource to block until it is downloaded, so you don't need to wrap the EmpathyX.init function inside of the initEmpathyX callback function in this situation.

<script src="https://assets.empathybroker.com/empathyx/{INSTANCE}/app.js"></script>
<script>
  EmpathyX.init({...});
</script>

A wild double scroll appeared in my search results page!

Well, this is most likely our fault, but please check if any of the following potential causes might be happening on your end: 

  • The main scrollable element is html instead of body: X is mounted in the body element and uses a special class called ebx-empathy-x--opened to disable its scroll while opened. This will not work if the scrollable element is html.
  • The default scroll behavior is overriden with JavaScript and interfering with X.