Releva has completed an $870,000 financial round led by New Vision Fund 3 with participation by HR Capital AD, Verto Invest and the investment arm of private investors.
Releva завърши финансов рунд от $870 000, воден от Фонд Ню Вижън 3 с участието на Ейч Ар Капитал АД, Верто Инвест и подкрепата на частни инвеститори.
Search the Documentations
Categories

Standard Integration

Integrate Releva in 12 easy steps.

This page will guide you through a full integration of your shop with Releva using our JavaScript library and a few backend calls. 

Step 1: On each page

Just add the following towards the end of the body element in HTML.

<script async type="text/javascript" src="https://releva.ai/sdk/v0/js/releva-sdk-js.min.js" onload="document.dispatchEvent(new Event('relevaSdkLoaded'));"></script>

The onload attribute and the document.addEventListener(..) wrapper are necessary to ensure that the Releva.push call is attempted after the SDK has finished loading. You are free to use alternative methods for ensuring the proper execution sequence is followed.

Then, whenever your page has loaded, make the following request. Please make sure to replace all values in the snippet below with the actual values! In the products.custom field, please out the specific values of any configurable product attributes that the user has selected before adding each product to their cart.

document.addEventListener('relevaSdkLoaded', function() {
  Releva.push("<yourAccessToken>", {
     "cart": {
        "products":  [
          {
            "id": "",
            "price": 0,
            "currency": "",
            "quantity": 0,
            "custom": {
              "string": [
                {"key": "color", "values": ["red"]}
              ],
              "numeric": [
                {"key": "size", "values": [18]}
              ]
            }
          }
       ]
    },
    "profile": {
      "firstName": "",
      "lastName": "",
      "email": "",
      "registeredAt": "YYYY-mm-ddT00:00:00.000Z",
      "location": {"lat": 39.9352959, "lon": 23.5825895}
    },
    "wishlist": {
      "products": [
        {"id": "...}
      ]
    }
  }, function(results) {
    // TODO: callback to implement rendering of custom recommenders and banners
  }, function (error) {
    console.error(error);
  });
});

Hint: If a user removes the last item from their cart, and their cart is deleted, please send a request with an empty products list. Example below:

...
"cart": {
  "products": []
},
...

The context.cart Object

This object describes the current state of the visitor’s cart. It should be set whenever a visitor’s cart is not empty.

FieldTypeDescription
productsArray[Object]A list of products in the cart.
products[].idStringA unique product id. Should be identical to context.product.id for a given product. Note that if you have a multi-locale shop ( you sell in multiple languages / currencies), this id will need to be unique across all locales.
products[].priceFloatThe unit price at which this product was purchased.
products[].currencyISO-4217 String (Optional)The product currency. This field is required if you sell products in multiple currencies.
products[].quantityIntegerThe quantity purchased.
products[].customObject (Optional)The custom fields are associated with the product.

The context.profile Object

This object describes the currently logged-in visitor. It should be set whenever a visitor is logged in.

FieldTypeDescription
firstNameString (Optional)Visitor’s first name.
lastNameString (Optional)Visitor’s last name.
emailString (Optional)Visitor’s email address.
phoneNumberString (Optional)Visitor’s phones number. Phone numbers must start with “+” followed by a sequence of numbers. Valid phone number: +49875345976.
registeredAtISO-8601 String (Optional)The date and time when this visitor created their account.
customObject (Optional)The custom fields are associated with the profile.
locationObject (Optional)The location of the user represented as coordinates in decimal notation
location.latFloatThe latitude of the visitor
location.lonFloatThe longitude of the visitor

The context.wishlist Object

This object describes the products currently in the user’s wishlist

FieldTypeDescription
products[].idStringThe id of a product in the wishlist
products[].customObject (Optional)The custom fields are associated with the product configuration – e.g. chosen size and color

Step 2: On product pages

Find the Releva.push(...) invocation you added in Step 1. Then, add the following to the second parameter:

"page": {
  "token": "<yourProductPageToken>",
  "categories": ["men/shoes/sport"]
},
"product": {
  "id": ""
}

The context.page Object

The Context Object describes the page the user is currently viewing. All fields are required unless stated otherwise.

FieldTypeDescription
tokenString (Optional)The page token of the currently visited page (e.g. home page, product page, cart page, etc.) Consult with your admin panel to find the right token to use. If you do not wish to obtain personalized content, you may omit this.
localeISO 639-1 StringThe page locale (e.g. enbg, etc.)
currencyISO-4217 String (Optional)The page currency. This field is required if you sell products in multiple currencies.
idsArray[String]If the user is visiting a listing page, set this to the list of product ids currently displayed. Otherwise, it should be omitted. Note that if you have a multi-locale shop ( you sell in multiple languages / currencies), each id will need to be unique across all locales.
categoriesArray[String]If the user is visiting a listing page, set this to the current categories selected.
customObject (Optional)The custom field filters are associated with the currently viewed product listing (for instance – shoe sizes 42, 43, 44).

The context.product Object

This object describes the currently viewed product if the visitor is on a product page. In all other cases, it should not be set.

FieldTypeDescription
idStringA unique product ID identifying your product. Note that if you have a multi-locale shop ( you sell in multiple languages / currencies), this id will need to be unique across all locales.
customObject (Optional)The custom fields associated with the currently viewed product, for example the currently selected shoe size.

Step 3: On the product listing page (e.g. category page)

Find the Releva.push(...) invocation you added in Step 1. Then, add the following to the second paramter:

"page": {
  "token": "<yourProductListingPageToken>",
  "ids": [],
  "categories": ["men/shoes/sport"],
  "filter": {
    "operator": "and",
    "nested": [
      {"key": "price", "operator": "gte", "value": "10", "action": "include"},
      {"key": "price", "operator": "lte", "value": "50", "action": "include"},
      {
        "operator": "or", 
        "nested": [
          {"key": "custom.string.size", "operator": "eq", "value": "42", "action": "include"},
          {"key": "custom.string.size", "operator": "eq", "value": "43", "action": "include"},
        ]
      }
    ]
  }
}

The context.page Object

The Context Object describes the page the user is currently viewing. All fields are required unless stated otherwise.

FieldTypeDescription
tokenString (Optional)The page token of the currently visited page (e.g. home page, product page, cart page, etc.) Consult with your admin panel to find the right token to use. If you do not wish to obtain personalized content, you may omit this.
localeISO 639-1 String (Optional)The product locale (e.g. enbg, etc.) This field is required if you sell products in multiple languages.
currencyISO-4217 String (Optional)The page currency. This field is required if you sell products in multiple currencies.
idsArray[String] (Optional)If the user is visiting a listing page, set this to the list of product ids currently displayed. Othersise, it should be omitted. Note that if you have a multi-locale shop ( you sell in multiple languages/currencies), each id will need to be unique across all locales.
queryString (Optional)The user query.
categoriesArray[String] (Optional)If the user is visiting a listing page, set this to the current categories selected.
customObject (Optional)The custom field filters associated with the currently viewed product listing (for instance – shoe sizes 42, 43, 44).
filterObject (Optional)The dynamic fields that should be applied

The context.page.filter object

This is an object with the following properties:

FieldTypeDescription
operatorStringIt has two values:
– “or” – used when we want only one condition from the sibling “nested” array to be true in order to return products
– “and” – used when we want every condition from the sibling “nested” array to be true in order to return products
nestedArrayIt contains all of the conditions you can check the conditions in the below table for context.nested. Also, you can nest inner conditions with a different “operator” if you append an object inside this array with the same fields “operator” and “nested”

The context.page.filter.nested array

This is an array of conditions used for the filter with the following properties:

FieldTypeDescription
keyStringThis can either be a standard field such as ‘price’ of a custom field of type, string, date, or numeric (e.g. custom.string.brand).
For a list of standard fields and examples of custom field notations please see product update API.
operatorStringThe operator you wish to use to check the value given in the “value” field against the value from the prouct catalog by the key given above.
We support these operators:
– eq – Equal to
– lt – Less than
– gt – Greater than
– lte – Less than or equal to
– gte – Greater than or equal to
– composite operators based on the last 4:
– gte,lte
– gte,lt
– gt,lte
– gt,lt
actionStringWhat action do you want to perform if the value checked with the operator has found products by the given key.
We support these actions:
– include – Include only the products that match the condition
– exclude – Exclude only the products that match the condition
– bury – Will make the products appear at the bottom of the search if they match the condition
– boost – Will make the products appear at the top of the search if they match the condition
valueStringThe value that you want to be checked in the products by the operator and key. Note that in case you use a composite operator (for ex. gte or any other combination of gt(e) and lt(e), the value must also consist of two distrinct values separated by a comma.
weightInteger (Optional)Weight is used only if you choose boost or bury in the action field and if you have more than one “boost” or “burry”, they will be ordered by the given weight.

Step 4: On search and search result pages

Find the Releva.push(...) invocation you added in Step 1. Then, make sure that your page object contains the ids property that will show the result from a search and a query object that defines the query of the user. Also include the filter object (see the previous step for detailed specification).

"page": {
  "token": "<tokenOfAnyPageWithSearchCapability>",
  "query": "my simple query",
  "ids": ["productId_id1", "productId_2", "productId_3"],
  "filter": {
    "operator": "and",
    "nested": [
      {"key": "price", "operator": "gte", "value": "10", "action": "include"},
      {"key": "price", "operator": "lte", "value": "50", "action": "include"},
      {
        "operator": "or", 
        "nested": [
          {"key": "custom.string.size", "operator": "eq", "value": "42", "action": "include"},
          {"key": "custom.string.size", "operator": "eq", "value": "43", "action": "include"},
        ]
      }
    ]
  }
},
...

Note that if you add the optional query parameter, the system will also add a search event. We highly recommend adding the ids field that must represent the result of the search query. The locale must represent both the page and query locale. In the rare event when they differ you shall describe search locale as a custom property.

Step 5: On checkout success pages

Find the Releva.push(...) invocation you added in Step 1. Then, change your cart[].products to contain not the list of products in the user’s cart, but the list of products that were part of the newly placed order.
Include the profile object with email and phoneNumber, if you have them (at least one is required, send both if you have both). Please ensure that the profile object is passed even if the order was placed via guest checkout and not by a registered user.

Note that you need to convert the phone number to a valid international format (e.g. if your shop operates in the U.S., you need to change 585-766-1234 to +15857661234; if the phone number cannot be converted in this way, do not include it in the request).

document.addEventListener('relevaSdkLoaded', function() {
  Releva.push("<yourAccessToken>", {
     "cart": {
        "products":  [
          {
            "id": "id_of_ordered_product",
            "price": 1,
            "currency": "USD",
            "quantity": 2,
            "custom": {
              "string": [
                {"key": "color", "values": ["red"]}
              ],
              "numeric": [
                {"key": "size", "values": [18]}
              ]
            }
          }
       ]
    },
    "profile": {
      "firstName": "",
      "lastName": "",
      "email": "",
      "phoneNumber": "+15857661234",
      "registeredAt": "YYYY-mm-ddT00:00:00.000Z",
    }
  }, function(results) {
    // TODO: callback to implement rendering of custom recommenders and banners
  }, function (error) {
    console.error(error);
  });
});

Note that if you add the optional query parameter, the system will also add a search event. We highly recommend adding the ids field that must represent the result of the search query. The locale must represent both the page and query locale. In the rare event when they differ you shall describe search locale as a custom property.

Step 6: Register service worker (Optional)

If you do not plan on using Releva to send push notifications, you may skip this step.

First, download service-worker.min.js and save it to the root of your site. You may change the name, but make sure you also change the name when you register it below.

Then we need to add the following object to the end of each Releva.push call:

document.addEventListener('relevaSdkLoaded', function() {
  Releva.push("<yourAccessToken>", {
  ...
  }, function(results) {
    ...
  }, function (error) {
    ...
  },
  // add this to register the service worker
  // please make sure you use the correct name here if you renamed the file
  // keep in mind this needs to point to the root of your domain
  {
    serviceWorkerUrl: '/service-worker.min.js'
  });
});

Step 7: Ensure data protection compliance

If you operate in countries where data protection laws such as GDPR, CCPA apply, you must implement an additional function which tells Releva if behavioral tracking for first-party marketing and analaytics is allowed.

In the last argument to Releva.push, you need to pass a function called hasConsent which returns true if behavioral tracking for first-party marketing and analaytics is allowed, or false otherwise.

document.addEventListener('relevaSdkLoaded', function() {
  Releva.push("<yourAccessToken>", {
  ...
  }, function(results) {
    ...
  }, function (error) {
    ...
  },
  // for example
  // if you have a cookie dialog which sets a cookie called 'cookielaw' with value '1' when the cooke is accepted
  // you need to implement the logic below for Releva to respect this setting
  {
    ....
    hasConsent: function() {
      return Releva.getCookie('cookielaw') === '1';
    }
  });
});

Step 8: Call the poduct update API call when changes in your catalogue occur

This is necessary for ensuring that changes in your catalogue are reflected in Releva in a timely manner. See Product Update for implementation details.

Step 9: Call the cart paid API when a customer places an order

See Cart Paid API for implementation details.

Step 10: Implement the periodical product sync API

This ensures that Releva will learn about changes in your catalogue even if your Product Update call does not work. It is highly recommended to implement this fallback mechanism. See Periodical Product Sync for implementation details.

Step 11: Send subscribes and unsubscribes to Releva

If you do not plan on using Releva to send emails or text messages, you may skip this step.

  1. When a user wishes to unsubscribe from receiving email or other marketing communication through Releva, you need to call the Unsubscribe API to notify Releva.
  2. When a user wishes to subscribe to receiving email or other marketing communication through Releva, you need to call the Subscribe API to notify Releva.

Step 12: Send newly registered users to Releva.

When a new user registers on your shop, you need to call the Profile Register API to notify Releva.

All Set!

Congratulations! This concludes the integration of your shop. Releva offers some advanced features that will help you achieve even better results. Feel free to explore the API Specification for information about how to send custom product and profile data, which can later be used in personalization. Also, feel free to look into the Data Deletion API and the Retrieve Tracked Data API which is designed to help you fulfill GDPR-related requests automatically.

View Article

Previous Private: Integration Guide
Next Server Side Integration
Table of Contents