Tracking External Search Interfaces

The v14 script provides a configuration that enables you to track external search interfaces — search boxes, suggestions, product detail pages, and checkout interfaces that aren't directly connected to our JavaScript plugin (for example if you're using API to render the search results, or if you want to track searches leading to sales).

To connect your custom interface to our insights tracking, you need to provide the external tracking configuration in your ss360Config :

window.ss360Config = {
   siteId: 'mysite.com',
   tracking: {
      external: { /*...*/ }
   }
}

This is either Site Search360 bundle loaded from js.sitesearch360.com or the v14 script loaded from cdn.sitesearch360.com/v14/sitesearch360-v14.min.js

If you're not using our Site Search 360 search script, you can also add a dedicated tracking script as follows:

<script>
window.ss360TrackingConfiguration = {
   siteId: 'mysite.com', // use project id instead of site id if you're using our ecommerce search
   baseUrl: 'https://ecom.sitesearch360.com/insights?projectId={PROJECT_ID}', // set this only if you're using our ecommerce search, and replace {PROJECT_ID} with your project id
   interface: {
      /*...*/
   }
}
</script>
<script defer src="https://cdn.sitesearch360.com/ss360-tracker.min.js"></script>

Note: All statistics tracked by the external tracking will be merged with your general search statistics for the given Site ID.

Initialization strategies

An initialization strategy specifies when the events should be attached to the search interface:

  • on load (default behavior)

  • when an element becomes rendered into the DOM

  • when an element (or document) is mutated

On Load

All events are attached when the script is executed:

{
   type: 'onload'
}

This strategy should be used when all UI elements are in the DOM immediately after the page is loaded.

Element being rendered into the DOM

Events will be attached once a given selector matches a node in the DOM, you can control the interval to specify how frequently the script should look for a matching node:

{
   type: 'interval',
   waitForElem: '#serp',
   duration: 250
}

This strategy should be used when an element (for example a search result block) is injected asynchronously to the DOM.

Element being mutated

Events will be (re-)attached every time an element (or the entire document if no wrapper is specified) gets mutated:

{
   type: 'observer',
   wrapper: '#serp'
}

This strategy can be helpful for example if your pagination loads and renders the next page of search results asynchronously without a page reload.

Expected conditions

Expected conditions define one or multiple conditions that need to be fulfilled in order for a specific set of events to be attached. For example if your search result page is available under https://mydomain.com/search you can specify the /search regular expression the URL has to match for the search result page tracking to be initialized.

There are three types of expected conditions you can define. if multiple conditions are provided, all have to be fulfilled in order for the events to be initialized:

  • URL Regex — a regular expression the URL must match

  • Search Param — a query parameter that must be present in the URL

  • DOM Element — a CSS selector, a matching element must be present in DOM

{
   urlRegex: '/search',
   searchParam: 'q',
   domElement: '#search-results'
}

Data sources

A data source defines where a particular information (for example the search query) should be extracted from.

Query Parameter

The data is extracted from a query parameter:

{
   type: 'urlParam',
   paramName: 'q'
}

URL Regex

A regular expression is applied on the URL and the data get extracted from a matching group:

{
   type: 'urlRegex',
   groupIndex: 0,
   regex: '/search/(.*)'
}

DOM Element

The data is extracted from the first DOM element matching a given CSS selector. By default the inner text is extracted. An attribute value can be extracted by providing the attribute name prefixed by the @ sign. If a source is given, and it is not prefixed by the @ sign, a property of the element will be used (e.g. clientWidth).

If the data source is being extracted after a search suggestion or search result is selected, after a product has been added to a cart, or within the checkout, the CSS selector will be relative to the single result/product node:

{
   type: 'domElement',
   selector: '#product',
   source: '@data-article-number'
}

Getter

The data is provided by a custom function. If the getter is called after a search suggestion or search result is selected, after a product has been added to a cart, or within the checkout, it will receive a DOM element (a single result/product) as a first argument:

{
   type: 'getter',
   getter: function(result) { return result.getAttribute('id').split('-')[0]; }
}

DOM Object

The data is extracted from a JSON object that is present in the DOM (inner text of a node), you need to specify a JPath to point to the property you want to extract:

{
   type: 'domJson',
   objectSelector: '#products-json',
   jpath: 'products[0]/price'
}

Window Object

The data is extracted from an object that is attached to the window, you need to specify a JPath to point to the property you want to extract:

{
   type: 'windowJson',
   propertyName: 'Products',
   jpath: 'data/price'
}

Static

The data is a static value:

{
   type: 'static',
   value: '€'
}

Configuration

By connecting your search box (ss360Config.tracking.external.searchBox) to the Site Search 360 tracking, you will get an overview of what queries were submitted to the search. A search box and search button CSS selector, and an initialization strategy can be configured:

{
   selector: '#searchBox',
   button: '#searchButton',
   initializationStrategy: {
      type: 'onload'
   },
   initCallback() { console.log('Search Box events initialized'); }
}

Search suggestions

By connecting your search suggestions dropdown (ss360Config.tracking.external.searchSuggestions), you will get an overview of what pages were followed from your suggestion box and what queries led to those.

To connect your search suggestions to the Site Search 360 tracking, you need to specify the suggestion block, suggestion item, and active suggestion item CSS selectors. Additionally, you can set an initialization strategy, and data sources pointing to the article number and/or unique identifier of the selected search suggestion (to connect your suggestions to the checkout tracking):

{
   blockSelector: '.search-suggest',
   itemSelector: '.search-suggest__item',
   activeItemSelector: '.search-suggest__item--selector',
   initializationStrategy: {
      type: 'observer',
      wrapper: '.search-suggest'
   },
   articleNumberSource: {
      type: 'domElement',
      selector: 'input[name="sku"]',
      source: '@value'
   },
   identifierSource: {
      type: 'domElement',
      selector: 'input[name="product-id"]',
      source: '@value'
   },
   initCallback() { console.log('Search Suggestion events initialized'); }
}

Search result page

By connecting your search result page (ss360Config.tracking.external.searchResults), you will get an overview of all the queries, their CTRs, and what results have been selected. To connect your search result page to the Site Search 360 tracking, you need to provide a block CSS selector, a result item CSS selector, a query data source, and expected conditions.

Additionally you can tweak the tracking with the following settings:

  • Exclude selector — a CSS selector pointing to nodes within a single search results that should not be tracked as a click-through (e.g. add to wishlist button)

  • Group selector — a CSS selector pointing to a single content group (e.g. if you split your search results into multiple tabs groupped by a category)

  • Initialization strategy

  • Article number and identifier data sources — to connect your search result page to checkout tracking

{
   blockSelector: '.search-result',
   itemSelector: '.search-result__item',
   singleGroupSelector: '.search-result__group',
   querySource: {
      type: 'urlParam',
      paramName: 'q'
   },
   expectedConditions: {
      urlRegex: '/search',
      searchParam: 'q'
   },
   articleNumberSource: {
      type: 'domElement',
      selector: 'input[name="sku"]',
      source: '@value'
   },
   initCallback() { console.log('SERP events initialized'); }
}

Product detail page

By connecting your product detail page (ss360Config.tracking.external.productDetailPage), you will be able to track all Add to Cart events that were triggered after a product has been followed from your search suggestions or search result page.

For a product to be considered as followed from search suggestions or search result page, the link, identifier, or article number must match the data tracked on the Search Result Page/within Search Suggestions.

For tracking to be working on the product detail page make sure that you didn't disable cookies by setting ss360Config.allowCookies = false; or disabling Tracking -> Allow cookies.

To connect your product detail page to the Site Search 360 tracking, you need to add the following settings:

  • Trigger a CSS selector pointing to your add to cart button or form

  • Article Number Data Source or Identifier Data Source — the source of an article number or unique identifier

  • Price Data Source — the source of the product price (for a single unit)

  • Price Unit Data Source — the source of the price unit

  • Count Data Source — the source of the number of products being added to cart

  • Expected Conditions — the conditions identifying a product detail page

Additionally, the following settings can be added:

  • Wrapper CSS Selector — specifying this will make all DOM element data source selectors relative to the given node

  • Link Data Source — by default the URL open in the browser is tracked as the product link, you can specify a data source for the link to track a normalized value

  • Initialization Strategy

{
   trigger: '#add-to-cart',
   expectedConditions: {
      urlRegex: '/p/'
   },
   articleNumberSource: {
      type: 'domElement',
      selector: 'input[name="sku"]',
      source: '@value'
   },
   priceSource: {
      type: 'domElement',
      selector: 'meta[name="price"]',
      source: '@content'
   },
   priceUnitSource: {
      type: 'static',
      value: '€'
   },
   countSource: {
      type: 'domElement',
      selector: 'input[name="count"]',
      source: 'value'
   },
   initCallback() { console.log('PDP events initialized'); }
}

Checkout

By connecting your checkout interface (ss360Config.tracking.external.checkout), you will be able to track what products have been bought after a product has been followed from your search suggestions and/or search results. You can also set the trackAll property to true to track every single product bought.

For a product to be considered as followed from search suggestions or search result page, the link, identifier, or article number must match the data tracked on the Search Result Page/within Search Suggestions.

For tracking to be working on the checkout page make sure that you didn't disable cookies by setting ss360Config.allowCookies = false; or disabling Tracking -> Allow cookies.

To connect your checkout interface to the Site Search 360 tracking, you need to add the following settings:

  • Trigger a CSS selector pointing to a button or form which completes the order

  • Expected Conditions

Additionally you need to specify one of the following three data sources that can be used to collect the information about all products that are in the cart (see type definitions below):

  • Checkout item source (CheckoutItemSource interface)

    • A CSS selector pointing to a single product in cart

    • Article number, link, identifier, unit price, price unit, and count data sources

  • Checkout item object source (CheckoutItemObjectSource interface)

    • A CSS selector pointing to a DOM element that includes a JSON array holding the cart data, or a window property name pointing to a global array holding the cart data

    • Article number, link, identifier, unit price, price unit, and count JPaths

  • Checkout data getter (CheckoutDataGetter interface)

    • A custom function returning an array of products in cart

    • Every entry should have the following properties: articleNumber, link, identifier, unitPrice, priceUnit, and count

If your checkout page is dynamic, you can also provide an Initialization Strategy.

{
   expectedConditions: {
      urlRegex: '/cart$'
   },
   trigger: '#checkout',
   itemSource: {
      selector: '.order__item',
      articleNumberSource: {
         type: 'domElement',
         selector: '.link',
         source: '@data-sku'
      },
      linkSource: {
         type: 'domElement',
         selector: '.link',
         source: '@href'
      },
      unitPriceSource: {
         type: 'domElement',
         selector: '.link',
         source: '@data-price'
      },
      priceUnitSource: {
         type: 'static',
         value: 'EUR'
      },
      countSource: {
         type: 'domElement',
         selector: 'input[name="quantity"]',
         source: '@value'
      }
   },
   initCallback() { console.log('Checkout events initialized'); }
}

Type definitions

/* external-tracking.types.ts */
enum InitializationStrategyType {
   Onload = 'onload',
   Interval = 'interval',
   Observer = 'observer'
}

interface InitializationStrategy {
   type: InitializationStrategyType,
   duration?: number,
   waitForElem?: string,
   wrapper?: string
}

enum DataSourceType {
   UrlParam = 'urlParam',
   UrlRegex = 'urlRegex',
   DomElement = 'domElement',
   Getter = 'getter',
   DomObject = 'domJson',
   WindowObject = 'windowJson',
   Static = 'static'
}

interface Getter {
   (domElement? : Element) : any
}

interface DataSource {
   type: DataSourceType,
   paramName?: string,
   regex?: string,
   groupIndex?: number,
   selector?: string,
   source?: string,
   getter?: Getter,
   objectSelector?: string,
   propertyName?: string,
   jpath?: string,
   value?: string
}

interface ExpectedConditions {
   urlRegex?: string,
   searchParam?: string,
   domElement?: string
}

interface SearchBoxConfiguration {
   selector: string,
   button?: string,
   initializationStrategy?: InitializationStrategy
}

interface SuggestionsConfiguration {
   blockSelector: string,
   itemSelector: string,
   activeItemSelector: string,
   initializationStrategy?: InitializationStrategy,
   articleNumberSource?: DataSource,
   identifierSource?: DataSource
}

interface ProductDetailPageConfiguration {
   trigger: string,
   wrapper?: string,
   articleNumberSource?: DataSource,
   identifierSource?: DataSource,
   linkSource?: DataSource,
   priceSource: DataSource,
   priceUnitSource: DataSource,
   countSource: DataSource,
   expectedConditions: ExpectedConditions,
   initializationStrategy?: InitializationStrategy
}

interface SearchResultsConfiguration {
   blockSelector: string,
   itemSelector: string,
   excludeActiveSelector?: string,
   singleGroupSelector?: string,
   querySource: DataSource,
   expectedConditions: ExpectedConditions,
   initializationStrategy?: InitializationStrategy,
   articleNumberSource?: DataSource,
   identifierSource?: DataSource
}

interface CheckoutEntry {
   articleNumber?: string,
   link?: string,
   identifier?: string,
   unitPrice?: number,
   priceUnit?: string,
   count?: number
}

interface CheckoutDataGetter {
   () : Array<CheckoutEntry>
}

interface CheckoutItemSource {
   selector: string,
   articleNumberSource?: DataSource,
   linkSource?: DataSource,
   identifierSource?: DataSource,
   unitPriceSource?: DataSource,
   priceUnitSource?: DataSource,
   countSource?: DataSource
}

interface CheckoutItemObjectSource {
   selector?: string,
   windowProperty?: string,
   entryJPath: string,
   articleNumberJPath?: string,
   linkJPath?: string,
   identifierJPath?: string,
   unitPriceJPath?: string,
   priceUnitJPath?: string,
   countJPath?: string
}

interface CheckoutConfiguration {
   trigger: string,
   expectedConditions: ExpectedConditions,
   getter?: CheckoutDataGetter,
   itemSource?: CheckoutItemSource,
   itemObject?: CheckoutItemObjectSource,
   initializationStrategy?: InitializationStrategy,
   trackAll?: boolean
}

interface TrackingConfiguration {
   searchBox?: SearchBoxConfiguration,
   searchSuggestions?: SuggestionsConfiguration,
   searchResults?: SearchResultsConfiguration,
   productDetailPage?: ProductDetailPageConfiguration,
   checkout?: CheckoutConfiguration
}