Data-driven event tracking

Behavioral tracking plays an important role in utilizing Constructor's full potential. The behavioral data we capture helps us generate learnings and is used to re-rank and personalize results for the end user.

We have observed that utilizing a data-driven approach helps to insulate from breakage when compared to using more traditional CSS selectors. This also ensures easy observability of what data is being utilized by Constructor to inform our ML platform.

The following sections outline the different data attributes that need to be surfaced for each product to take advantage of all of Constructor's beacon tracking features.

Autocomplete

Please surface the following data attributes for the elements specified below:

📘

Note

Exposing of data attributes is not required if making use of Constructor's open source Autocomplete UI library - tracking is automatically handled as part of the library capabilities.

Form element

Add the following data attribute to the form element that is the parent of the input element where the user types their search query:

data-cnstrc-search-form

Search input

Add the following data attribute to the input element where the user types their search query:

data-cnstrc-search-input

Search submit button

Add the following data attribute to the element (typically a button) that submits the user's search query:

data-cnstrc-search-submit-btn

Results list container

Add the following data attribute to the parent container housing autocomplete results:

data-cnstrc-autosuggest

Result item

Add the following data attributes to each suggestion result item within the autocomplete container:

data-cnstrc-item-section="[section name]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-id="[item id]" // conditionally included - see notes below
data-cnstrc-item-group="[item group id]" // conditionally included - see notes below
  • Section names pertain to the different sections within an index (case sensitive). For example, "Search Suggestions" or "Products"
  • data-cnstrc-item-id is not applicable to results from the "Search Suggestions" section and should otherwise not be included
  • data-cnstrc-item-group is only applicable to "Search in Category" results and should otherwise not be included
  • Item names and IDs should match with the values being supplied within the catalog files being supplied to Constructor.

Example markup

Search input

<form id="search-form" method="get" action="/search">
  <input
    class="search-input"
    type="text"
    placeholder="Search for products"
    autocomplete="off"
    data-cnstrc-search-input
  />
  <button
    class="search-submit-button"
    type="submit"
    data-cnstrc-search-submit-btn
  >
    <i class="fas fa-search"></i>
  </button>
</form>

Autocomplete

<div id="autosuggest" data-cnstrc-autosuggest>
  <ul class="search-suggestions">
    <li
      class="search-suggestion"
      data-cnstrc-item-section="Search Suggestions"
      data-cnstrc-item-name="apple"
      data-cnstrc-item-group="fruits-vegetables"
    >
      <a href="https://www.example.com/search?q=apple&filters[group_id]=fruits-vegetables">
        <span>apple in Fruits / Vegetables</span>
      </a>
    </li>
    <li
      class="search-suggestion"
      data-cnstrc-item-section="Search Suggestions"
      data-cnstrc-item-name="apple"
    >
      <a href="https://www.example.com/search?q=apple">
        <span>apple</span>
      </a>
    </li>
    ...
  </ul>
  <ul class="product-suggestions">
    <li
      class="product-suggestion"
      data-cnstrc-item-section="Products"
      data-cnstrc-item-name="Organic Fuji Apples"
      data-cnstrc-item-id="product_id_1"
    >
      <a href="https://www.example.com/product/product_id_1">
        <img src="https://www.example.com/images/product_id_1.png">
        <span>Organic Fuji Apples</span>
      </a>
    </li>
    ...
  </ul>
  ...
</div>

Search & browse

Please surface the following data attributes for the elements specified below:

Results list container (search)

Add the following data attribute to the element that contains all of the search result items:

data-cnstrc-search
data-cnstrc-num-results="[total number of results]"

📘

Note

These 2 tags should also be exposed on zero results pages

Results list container (browse)

Add the following data attributes to the element that contains all of the browse result items:

data-cnstrc-browse
data-cnstrc-num-results="[total number of results]"
data-cnstrc-filter-name="[filter name]" // conditional - see notes below
data-cnstrc-filter-value="[filter value]" // conditional - see notes below
  • data-cnstrc-filter-name and data-cnstrc-filter-value values are only applicable when results are powered by Constructor and can be omitted otherwise.
  • data-cnstrc-filter-name contains the filter name being used in the browse request to power the product listing page. Possible values are: "group_id," "collection_id," or "[facet_name]" where the facet name corresponds with a facet defined within the catalog files. For example, "brand."
  • data-cnstrc-filter-value contains filter value that's being used in the browse request to power the product listing page. For example, "men-jeans."
  • The values defined for filter name and filter value should correspond exactly to the values being supplied with browse requests to Constructor. An browse request URL typically follows the pattern: /browse/[filter-name]/[filter-value], ex: /browse/group_id/mens-jeans

Result item

Add the following data attributes to each result item within the search or browse result container:

data-cnstrc-item-id="[item id]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-variation-id="[variation id]" // conditional - see notes below
data-cnstrc-item-price="[item price]" // conditional - see notes below
data-cnstrc-sl-campaign-id="[sponsored listing campaign id]" // conditionally included - see notes below
data-cnstrc-sl-campaign-owner="[sponsored listing campaign owner]" // conditionally included - see notes below
  • data-cnstrc-item-variation-id should be populated only if there is a face out variation shown or selected.
    • For results that display swatches (that is, colors), this value should be updated accordingly if the product URL the user would be redirected to changes when interacting with swatches.
    • If results are powered by Constructor, this value should default to the variation_id surfaced on the result level - located within the response at response.results[index].data.variation_id.
  • data-cnstrc-item-price should be populated only if there is a conversion / call to action button available for interaction (such as add to cart, add to wishlist, etc.). The value should be numeric - the minimum between the sale price (if available) and the retail (or MSRP) price.
  • data-cnstrc-sl-campaign-id should be populated only if the item is a part of a sponsored listing campaign. This ID can be within the response at response.results[index].labels.sl_campaign_id
  • data-cnstrc-sl-campaign-owner should be populated only if the item is a part of a sponsored listing campaign. This information can be found within the response at response.results[index].labels.sl_campaign_owner

Conversion / call to action buttons

Add the following data attributes to any conversion or call to action buttons within the result item container:

data-cnstrc-btn="[conversion type]"

Example markup

If the product has multiple variations that can be selected, please make sure to update data-cnstrc-item-variation-id to reflect the correct variation when the user updates their selection.

Search

<div
  class="search-results-grid"
  data-cnstrc-search
  data-cnstrc-num-results="246"
>
  <div
    class="search-result"
    data-cnstrc-item-id="product_371823"
    data-cnstrc-item-name="Organic Honeycrisp Apple"
    data-cnstrc-item-variation-id="product_371823_A1"
  >
  	<a href="https://www.example.com/product/product_371823">
    	<img src="https://www.example.com/images/product_371823.png"/>
      <span>Organic Honeycrisp Apple</span>
    </a>
   	<button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist">Add to wishlist</button>
    <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart">Add to cart</button>
  </div>
  ...
</div>

Browse

<div
  class="browse-results-grid"
  data-cnstrc-browse
  data-cnstrc-num-results="246"
  data-cnstrc-filter-name="group_id"
  data-cnstrc-filter-value="fruits"
>
  <div
    class="browse-result"
    data-cnstrc-item-id="product_371823"
    data-cnstrc-item-name="Organic Honeycrisp Apple"
    data-cnstrc-item-variation-id="product_371823_A1"
  >
    <a href="https://www.example.com/product/product_371823">
      <img src="https://www.example.com/images/product_371823.png"/>
      <span>Organic Honeycrisp Apple</span>
    </a>
    <button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist">Add to wishlist</button>
    <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart">Add to cart</button>
  </div>
  ...
</div>

Exposing request object and result ID

In addition to the data attributes preceding, when Constructor is powering search or browse results, the request object and the result_id from Constructor's API response should be surfaced on the product listing pages as a JSON string within a cnstrc-datascript tag.

This script tag should only be surfaced on search or browse product listing pages where results are powered by Constructor and not supplied on any other pages.

📘

Note

Exposing of the script tag is not required if making use of Constructor's open source JavaScript client library - tracking is automatically handled as part of the library capabilities.

<script id="cnstrc-data" type="application/json">
  {
    "request": { ... },
    "result_id": "<result_id>",
  }
</script>

Recommendations

Please surface the following data attributes for the elements specified below:

Results list container

Add the following data attributes to the element that contains the recommendations results:

data-cnstrc-recommendations
data-cnstrc-recommendations-pod-id="[pod id]"
data-cnstrc-result-id="[result id]"
data-cnstrc-num-results="[total number of results]"
  • The pod ID for data-cnstrc-recommendations-pod-id is available in Constructor's API response under response.pod.id and also defined within the Customer Dashboard. For example, data-cnstrc-recommendations-pod-id="pdp_complementary_items"
  • The result ID for data-cnstrc-result-id is available on the top level data in Constructor's API response.
  • data-cnstrc-num-results should contain the total number of results returned from Constructor's API response.

Result item

Add the following data attributes to each result item within the recommendations results container:

data-cnstrc-item="recommendation"
data-cnstrc-item-id="[item id]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-variation-id="[variation id]"
data-cnstrc-strategy-id="[strategy id]"
data-cnstrc-item-price="[item price]" // conditional - see notes below
  • data-cnstrc-item-variation-id should be populated only if there is a face out variation shown or selected.
    • For results that display swatches (that is, colors), this value should be updated accordingly if the product URL the user would be redirected to changes when interacting with swatches.
    • If results are powered by Constructor, this value should default to the variation_id surfaced on the result level - located within the response at response.results[index].data.variation_id.
  • The strategy ID for data-cnstrc-strategy-id is available in Constructor's API response under response.results[index].strategy.id. For example, data-cnstrc-strategy-id="complementary_items".
  • data-cnstrc-item-price should be populated only if there is a conversion / call to action button available for interaction (such as add to cart, add to wishlist, etc.). The value should be numeric - the minimum between the sale price (if available) and the retail (or MSRP) price.

Conversion / call to action buttons

Add the following data attributes to any conversion or call to action buttons within the result item container:

data-cnstrc-btn="[conversion type]"

Example markup

If the item has multiple variations that can be selected, please make sure to update data-cnstrc-item-variation-id to reflect the correct variation when the user updates their selection.

<div
  class="recommendations-carousel"
  data-cnstrc-recommendations
  data-cnstrc-recommendations-pod-id="pdp_complementary_items"
  data-cnstrc-num-results="10"
  data-cnstrc-result-id="aabae837-bd93-4d98-8c81-36f8754419cb"
>
  <div
    class="recommendation"
    data-cnstrc-item="Recommendation"
    data-cnstrc-item-id="product_778787"
    data-cnstrc-item-name="Short Sleeve Shirt"
    data-cnstrc-item-variation-id="829391312"
    data-cnstrc-strategy-id="complementary_items"
  >
    <a href="https://www.example.com/product/product_778787">
      <img src="https://www.example.com/images/product_778787.png"/>
      <span>Short Sleeve Shirt</span>
    </a>
    <button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist">Add to wishlist</button>
    <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart">Add to cart</button>
  </div>
  ...
</div>

Product detail pages

Product detail pages can take many forms, including things such as "Quick Shop," "Quick View" linked from product listing pages. Please surface the following data attributes for the elements specified below for all product detail views:

Detail container

Add the following data attributes to the element containing the product details:

data-cnstrc-product-detail
data-cnstrc-item-id="[item id]"
data-cnstrc-item-variation-id="[variation id]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-price="[item price]"
  • data-cnstrc-item-variation-id should be populated only if there is a face out variation shown or selected.
    • For results that display swatches (that is, colors), this value should be updated accordingly if the product URL the user would be redirected to changes when interacting with swatches.
    • If results are powered by Constructor, this value should default to the variation_id surfaced on the result level - located within the response at response.results[index].data.variation_id.
  • data-cnstrc-item-price should be populated only if there is a conversion / call to action button available for interaction (such as add to cart, add to wishlist, etc.) - this is generally the case on most product detail pages. The value should be numeric - the minimum between the sale price (if available) and the retail (or MSRP) price.

Conversion / call to action buttons

Add the following data attributes to any conversion or call to action buttons within the result item container:

data-cnstrc-btn="[conversion type]"

Example markup

If the item has multiple variations that can be selected, please make sure to update data-cnstrc-item-variation-id to reflect the correct variation when the user updates their selection.

<div
  id="product-detail"
  data-cnstrc-product-detail
  data-cnstrc-item-id="849291"
  data-cnstrc-item-variation-id="849291_42312"
  data-cnstrc-item-name="Relaxed Jogger"
  data-cnstrc-item-price="14.99"
>
  <div class="section">
    <h3>Relaxed Jogger</h3>
    <img src="https://www.example.com/images/product_849291.png">
    <span class="price">$19.99</span>
    <span class="sale-price">$14.99</span>
  </div>
  <button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist">Add to wishlist</button>
  <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart">Add to cart</button>
</div>

Order details / purchase confirmation page

Information about the order should be surfaced on the order details (purchase confirmation) page in either a variable in the browser window object, or a script tag. The data surfaced should contain the following information:

window.cnstrcPurchaseData = {
    items: [
        {
            item_id: '6501SB',
            variation_id: '387758',
            count: 1,
            price: 10,
        },
        ...
     ],
     order_id: '1AZ0941',
     revenue: 82.48,
};
  • variation_id should only be included if a specific item variation was purchased.
  • order_id should be a unique order identifier
  • revenue should be a numeric value that represents either the purchase subtotal or the total amount including taxes, discounts, etc. It should match what is tracked within any relevant analytics platforms.

Access to a QA, development, or production environment along with a test account and payment info will be needed to set up tracking.

Quizzes

Please surface the following data attributes for the elements specified below:

📘

Note

Exposing of data attributes is not required if making use of Constructor's open source Quizzes UI library - tracking is automatically handled as part of the library capabilities.

Results list container

Add the following data attribute to the element that contains all of the quizzes result items:

data-cnstrc-quizzes
data-cnstrc-quiz-id="[quiz id]"
data-cnstrc-quiz-version-id="[version id]"
data-cnstrc-quiz-session-id="[session id]"
data-cnstrc-result-id="[result id]"
data-cnstrc-num-results="[total number of results]"
  • data-cnstrc-num-results should contain the total number of results returned from Constructor's API response and can be located at response.total_num_results within the Quizzes API response.

Result item

Add the following data attributes to each result item within the quizzes results container:

data-cnstrc-item-id="[item id]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-variation-id="[variation id]" // conditional - see notes below
data-cnstrc-item-price="[item price]"
  • data-cnstrc-item-variation-id should be populated only if there is a face out variation shown or selected.
    • For results that display swatches (that is, colors), this value should be updated accordingly if the product URL the user would be redirected to changes when interacting with swatches.
    • If results are powered by Constructor, this value should default to the variation_id surfaced on the result level - located within the response at response.results[index].data.variation_id.
  • data-cnstrc-item-price should be populated only if there is a conversion / call to action button available for interaction (such as add to cart, add to wishlist, etc.). The value should be numeric - the minimum between the sale price (if available) and the retail (or MSRP) price.

Conversion / call to action buttons

Add the following data attributes to any conversion or call to action buttons within the result item container:

data-cnstrc-btn="[conversion type]"

Example markup

<div
  class="quiz-results-grid"
  data-cnstrc-quizzes
  data-cnstrc-quiz-id="my_quiz_id"
  data-cnstrc-quiz-version-id="11db5ac7-67e1-4000-9000-414d8425cab3"
  data-cnstrc-quiz-session-id="31f6bdae-6f1d-482f-b37f-f7a9e346973a"
  data-cnstrc-result-id="5fd4ddbb-f2ff-4430-8cd9-bad4b0fdc2b7"
  data-cnstrc-num-results="20"
>
  <div
    class="quiz-result-item"
    data-cnstrc-item-id="product_371823"
    data-cnstrc-item-name="Organic Honeycrisp Apple"
    data-cnstrc-item-variation-id="product_371823_A1"
    data-cnstrc-item-price="14.99"
  >
    <a href="https://www.example.com/product/product_371823">
      <img src="https://www.example.com/images/product_371823.png"/>
      <span>Organic Honeycrisp Apple</span>
    </a>
  	<button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist">Add to wishlist</button>
  	<button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart">Add to cart</button>
  </div>
  ...
</div>

AI Shopping Assistant

Please surface the following data attributes for the elements specified below:

Assistant result list container

Add the following data attributes to the ASA result container:

data-cnstrc-assistant
data-cnstrc-intent="[ASA request intent]"
data-cnstrc-intent-result-id="[ASA request result id]"
data-cnstrc-search-result-count="[total number of search results loaded]"
  • data-cnstrc-intent="[user intent]" should contain the intent (query) of the ASA request.
  • data-cnstrc-intent-result-id="[intent result id]"
    • Can be retrieved from the response.intent_result_id field of each data segment
  • data-cnstrc-search-result-count="[total number of search results]" should contain the number of different search query results loaded.
    • ASA responses contain results for multiple different queries (terms). This attribute should be the number of distinct query results loaded, not the number of items loaded per query.

Assistant search result container

Add the following data attributes to each ASA search result list container:

data-cnstrc-assistant-search
data-cnstrc-assistant-search-result-id="[ASA search query result id]"
data-cnstrc-num-results="[total number of results loaded]"
  • data-cnstrc-assistant-search-result-id="[assistant search result id]"
    • Can be retrieved from the response.result_id field of each data segment
  • data-cnstrc-num-results="[total number of results]"
    • The total number of results (items) returned for this search query result.

Result item

Add the following data attributes to each result item within the Assistant search result container

data-cnstrc-item-id="[item id]"
data-cnstrc-item-name="[item name]"
data-cnstrc-item-variation-id="[variation id]" // conditional - see notes below
data-cnstrc-item-price="[item price]" // conditional - see notes below
  • data-cnstrc-item-variation-id should be populated only if there is a face out variation shown or selected.
    • For results that display swatches (that is, colors), this value should be updated accordingly if the product URL the user would be redirected to changes when interacting with swatches.
    • If results are powered by Constructor, this value should default to the variation_id surfaced on the result level - located within the response at response.results[index].data.variation_id.
  • data-cnstrc-item-price should be populated only if there is a conversion / call to action button available for interaction (such as add to cart, add to wishlist, etc.). The value should be numeric - the minimum between the sale price (if available) and the retail (or MSRP) price.

Conversion / call to action buttons

Add the following data attributes to any conversion or call to action buttons within the result item container:

data-cnstrc-btn="[conversion type]"

Example markup

<div
  class="assistant-results-grid"
  data-cnstrc-assistant
  data-cnstrc-intent="Show me picnic recommendations"
  data-cnstrc-intent-result-id="5fd4ddbb-f2ff-4430-8cd9-bad4b0fdc2b7"
  data-cnstrc-search-result-count="2"
>
  <div
    class="assistant-search-result-grid"
    data-cnstrc-assistant-search
    data-cnstrc-assistant-search-result-id="1f2sdA-f2ff-4430-8cd9-bad4b0fdc2b7"
    data-cnstrc-num-results=5
  >
    <div
      class="assistant-search-result"
      data-cnstrc-item-id="product_371823"
      data-cnstrc-item-name="Organic Honeycrisp Apple"
      data-cnstrc-item-variation-id="product_371823_A1"
    >
      <a href="https://www.example.com/product/product_371823">
        <img src="https://www.example.com/images/product_371823.png"/>
        <span>Organic Honeycrisp Apple</span>
      </a>
      <button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist"/>
      <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart"/>
    </div>
  </div>
  <div
    class="assistant-search-result-grid"
    data-cnstrc-assistant-search
    data-cnstrc-assistant-search-result-id="2SDFEg-f2ff-4430-8cd9-bad4b0fdc2b7"
    data-cnstrc-num-results=5
  >
    <div
      class="assistant-search-result"
      data-cnstrc-item-id="product_371823"
      data-cnstrc-item-name="Organic Ham Sandwhich"
      data-cnstrc-item-variation-id="product_371845_A1"
    >
      <a href="https://www.example.com/product/product_371823">
        <img src="https://www.example.com/images/product_371823.png"/>
        <span>Organic Ham Sandwhich</span>
      </a>
      <button class="add-to-wishlist" type="button" data-cnstrc-btn="add_to_wishlist"/>
      <button class="add-to-cart" type="button" data-cnstrc-btn="add_to_cart"/>
    </div>
  </div>
</div>

Logged in user ID

Constructor’s product discovery service can be configured to accept user IDs to enable omnichannel personalization. With this technique, users who are logged into a website or app will receive consistent personalization across search, browse, recommendations, and other Constructor products as they change between mobile and desktop devices.

To protect our end users’ privacy, Constructor strives to avoid collecting any personally identifiable information (PII) across all its products. Therefore, we encourage our customers to obfuscate the user IDs they pass to us so that there’s no way for Constructor to be able to personally identify the users. We also do PII detection in our tracking beacon to ensure no personally identifying data is sent in our tracking calls.

For logged in users, the user ID should be exposed in the browser's window object under the name cnstrcUserId for the Constructor beacon to use for behavioral tracking calls. If the user is not logged in, this value should be omitted.

window.cnstrcUserId = "123XYZ123";

Test cells

When running an A/B test with Constructor, information about the test cell (that is, the experience or experiment) the user is in should be accessible on all pages through the browser's window object. If the user is not part of an active A/B test, this value should not be set.

window.cnstrcTestCell = "control";

When running an A/B test, possible values are:

  • control
  • constructor

When running an AA/BB test, possible values are:

  • control_1
  • control_2
  • constructor_1
  • constructor_2