Skip to content

Best Practices

The extensive customization options for Relewise leaves questions as to what the best approach is to a good setup. This article aims to provide the answer by offering best practice advice for every step you will go through. We urge you to read this document carefully before you commit to progressing through the implementation steps, to ensure that you get the most out of your Relewise integration.

Keep in mind that this is meant as a starting point for standard installations, and should serve as a baseline for further customization.

1. Product Integration

If your site requires search and recommendation of products, you will need to set up proper handling of product details to Relewise.

Best Practice for Product Integration

First, decide if you want to push or pull data between your store and the Relewise API. You can read more about the difference in pushing and pulling data here.

Relewise recommends pushing product data to the API. Pushing data is faster and potentially cheaper in licensing cost, and grants a higher level of control over when entities are pushed and how they are structured. Any time you need to update your entities with new data keys for use in your search and recommendations, it is made easier with the Push approach, since you control the exact detail of what is being sent to Relewise.

Pull synchronization, effectively means we will retrieve your feed on an agreed upon fixed interval. As a result, this involves a delay between when products are updated in your feed, and when products are updated in Relewise.

Relewise innately supports RSS 2.0 feeds, e.g. Google Shopping feed, as well as Shopify feeds. Other custom feeds can also be used, but will require billed work on our part to build the integration to consume your custom feed.

A note on Product and Variant IDs

If your site is operating with products that have variants, it is useful to know that while ProductID must be unique across the site, VariantID only needs to be unique to the product under which the variant is stored.



The First Product Import

Your import of products should include every product that is to be made available in your store via recommendation and/or search results from Relewise. ProductUpdate allows you to both create and update product entities; you can read more about it here.

Best practice for loading products into Relewise is to include as few product and variant fields as possible. To determine which fields to include, please refer to this checklist:

  • Should the field be text searchable?
  • Should results be able to be filtered on the basis of this field?
  • Should results be able to be sorted on the basis of this field?
  • Do you need this field returned to you in results from Relewise? This might be for instance a product image URL, which enables you to render the product image in your result UI, without needing to look up that image url in your own datastore after getting the result back from Relewise.

If you can answer yes to at least one of these, the field should be included. Otherwise, leave it out.

Each field you want to be text-searchable will be configured in the Search Index later on.

If you have multiple languages on your site, you should make sure to include data for each language in the relevant fields. For instance, if your site has an English and a German language component, you should include information for fields such as DisplayName in both English and German, using a Multilingual property.


Multilingual Properties

Even if your site only has a single language, we still urge you to use Multilingual properties for those of your fields that contain language specific text. Language invariant data such as an image path does usually not need to be multilingual, except if your site uses different images for different languages.

Using multilingual datatypes ensures that these fields are properly formatted and processed by the natural language processing built into Relewise. Whenever you receive results back from Relewise in later search and recommendation responses, we will ensure correct mapping of the language specific value for the selected fields, based on the language passed to us as part of the request.

csharp["ShortDescription"] = new Multilingual(
	new Multilingual.Value(en, "An English short description")

Example of a field with a Multilingual property


Product Updates

When running a full product update via ProductUpdate, we suggest that you include a timestamp field or similar identifier for when you perform the update.

product.Data["ImportedAt"] = importTimestamp;

This allows you to disable all products that were not included in the latest update, on the assumption that they have been removed from your site, and so should be removed from Relewise as well. By using this method, you can disable products that are out of stock, discontinued, etc, but still be able to reactivate them later as needed.

It is important to set this timestamp to the exact same value for all products being updated, such as by storing the timestamp in a variable before starting the integration. This ensures there are no changes to the timestamp while the integration is still running.

After performing the update, any product not affected by the update will have an old, unchanged timestamp from the last time it was updated.

var nonUpdatedProductsFilter = new FilterCollection(
	new ProductDataFilter("ImportedAt", new EqualsCondition(
		importTimestamp, negated: true)
	new ProductAdministrativeAction(
		Language.Undefined, Currency.Undefined, nonUpdatedProductsFilter, 

Example of disabling all products with an old time stamp

With the obsolete products disabled, you should also make sure to enable any products that may have been disabled in a previous update, but which are no longer meant to be disabled. Updating product data of a disabled product will not automatically re-enable the product.

To enable all imported product, similarly to the above, use the following, where we have set "negated" to false and change the update kind to "Enable":

var updatedProductsFilter = new FilterCollection(
	new ProductDataFilter("ImportedAt", new EqualsCondition(
		importTimestamp, negated: false)
	new ProductAdministrativeAction(
		Language.Undefined, Currency.Undefined, updatedProductsFilter,

Example of re-enabling disabled products with the latest time stamp

Keep in mind that this method does not apply to Delta updates, which in its nature only updates selected products.

Note that you use ProductAdministrativeAction to disable products, and ProductUpdate to create and update/enable them. Similarly, use ProductCategoryAdministrativeAction to disable product categories, and ProductCategoryUpdate to enable or update them.

2. Content Integration

Integrating Content into Relewise follows similar practices to Product Integration.

Content Integration Best Practices

First, decide if you want to push or pull data between your site and the Relewise API. You can read more about the difference in pushing and pulling data here

Relewise recommends pushing content data to the API. Pushing data is faster and potentially cheaper, and grants a higher level of control over the data stream and how it is formatted.


Importing Content Pages

The first time you import content to Relewise, it should include everything you want your users to see: About-pages, content categories, blog posts, documentation, legal documents etc. Calling ContentUpdate allows you to both create and update content entities; you can read more about it here.

Best practice for importing content pages into Relewise is to include as few fields as possible. If you are uncertain if a certain key should be included in the request, follow this checklist:

  • Should the field be text searchable?
  • Should results be able to be filtered on the basis of this field?
  • Should results be able to be sorted on the basis of this field?
  • Do you need this field to be returned in results from Relwise (eg. for displaying on the website)?

If you can answer yes to at least one of these, the field should be included. Otherwise, leave it out.

If you need to disable Content pages in Relewise, use ContentAdministrativeAction to disable them, and ContentUpdate to create and update/enable them. Similarly, use ContentCategoryAdministrativeAction to disable Content Categories, and ContentCategoryUpdate to update or enable them.


Multilingual Properties

Even if your site only has a single language, we still urge you to use Multilingual properties for those of your fields that are meant to be directly searchable. A data key for an image path does not require multilingual setup, but for fields that you know your users will engage with, using multilanguage properties ensures that these fields are properly formatted and affected by the natural language processing built into Relewise.

Example of a field with a Multilingual Property

csharp["Content"] = new Multilingual(
	new Multilingual.Value(en, "The English page content")
Click here for an example of Content Integration
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Relewise.Client;
using Relewise.Client.DataTypes;
using Relewise.Client.Requests;
using Relewise.Client.Requests.Conditions;
using Relewise.Client.Requests.Filters;
var contentItems = GetContentItemsAsync(); //example method - fetching contentitems in a particular format from a feed, a url or similiar
var importTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
//Authenticating against your API endpoint. Your serverUrl can be found in the Developer Settings in
var tracker = new Tracker(datasetId: Guid.Parse("<Your Dataset ID>"), apiKeySecret: "<Your API Key>", serverUrl:"<Your Server URL>");
//As we will import a list of contentItems, we want to make all the items trackable
var contentUpdates = new List<Trackable>();
//Looping over all over previously fetched content items
contentItems.ToList().ForEach(item =>
    //Converting each content item into a Content object and wrap that Content object in a ContentUpdate, allowing us to track the changes to the Content item. 
    contentUpdates.Add(new ContentUpdate(ConvertToContentItem(item, importTimeStamp), ContentUpdate.UpdateKind.ReplaceProvidedProperties));
//Disable all content entities not included in above update, since they will have another timestamp. If you create a DELTA UPDATE - you should handle this differently. 
    var disable = new ContentAdministrativeAction(
    new FilterCollection(new ContentDataFilter("LastImported", new EqualsCondition(importTimeStamp, negated: true))), 
//Make sure that we enable ALL content that was involved in the import!
var enable = new ContentAdministrativeAction(
    new FilterCollection(new ContentDataFilter("LastImported", new EqualsCondition(importTimeStamp, negated: false))), 
catch (System.Exception)
    //handle your errors - if something fails, make sure that you check what and correct.
//If everything works, you should be able to search for Content in the Content Section in Entities in
//Example method converting a JSON representation of a Content item to a Relewise Content object. 
//In this example we chose to work with Newtonsoft 
static Content ConvertToContentItem(JToken jsonObject, long lastImportDate)
    //Setup properties that will be needed. 
    //In this example we add multilingual content - hence multiple languages
    Language da = new Language("da");
    Language en = new Language("en");
    if (jsonObject is not null)
        //When creating a new Content object, add a unique ID
        var c = new Content(jsonObject["id"].ToString());
        c.Data["Title"] = jsonObject["title"].ToString();
        //An example of adding multilingual data to the Displayname
        c.DisplayName = new Multilingual(new Multilingual.Value(da, jsonObject["title"].ToString()), new Multilingual.Value(en, jsonObject["title"].ToString()));
        //Multilingual data allows for better search through natural language processing
        //Data is a Key/Value collection and value can be a number, a string, a boolean, a currency, a data object, or any list of the former.
        c.Data["Type"] = new Multilingual(new Multilingual.Value(da, jsonObject["type"].ToString()));
        c.Data["Link"] = jsonObject["link"].ToString();
        //When working with Content data, we currently support up to 10.000 characters in our text fields, and recommend that HTML tags etc. are stripped when pushing data to the index. 
        //An alternate solution is to change the parser on the Index field to HTML in
        c.Data["Excerpt"] = RemoveHtmlTags(jsonObject["excerpt"].ToString());
        c.Data["Date"] = jsonObject["date"].ToString();
        c.Data["Content"] = RemoveHtmlTags(jsonObject["content"].ToString());
        //Imagine that a JSON field could look like {taxonomy_value1, taxonomy_value2, taxonomy_value3, taxonomy_value4}
        //The MultilingualCollection will allow you to create the Field as a queryable collection that can easily be used as facets as well
        c.Data["Tags"] = new MultilingualCollection(da, jsonObject["tags"].ToString().Split(',').Select(tag => tag.Trim()).ToList());
        //Set the specfic time for this import
        c.Data["LastImported"] = lastImportDate;
        return c;
    return null;
static JArray GetContentItemsAsync()
    //Get All Contentitems. 
    //Method could return a JArray
    return new JArray();
static string RemoveHtmlTags(string text)
    //Remove All HTML from your text
    return "CleanString";

3. Behavioral Tracking

Relewise relies on knowledge of user behavior to personalize the experience. Setting up behavioral tracking is essential to ensuring a good integration of Relewise into your website.

Best Practice for Behavioral Tracking.

Behavioral tracking is ideally set up before you implement the Search and/or Recommendations services to your site. This gives the system the opportunity to "warm up the engine", and ensures that you will be seeing personalized content from day one of your service implementation.

User tracking consists of a few parts:

  • A User ID (if the user is non-anonymous)
  • The event being tracked
  • The Entity ID of the event being tracked
var productView = new ProductView(
    new ProductAndVariantId("product-1")

Example of a Behavioral Tracking request


Tracking User data is contingent on the user having accepted or rejected tracking cookies on the website. To ensure that your site is GDPR-compliant and sorts properly between users who have agreed to being tracked and those who have not, you may wish to integrate to an external provider of GDPR compliancy solutions. For examples on how to integrate these services into Relewise, refer to our examples page.

To get the most out of your Relewise integration, you should familiarize yourself with the different types of users that Relewise operates with. You can read about them in this article.

We recommend that you store your Users' Temporary ID somewhere persistent, such as on local storage or in a persistent cookie. It is important that this ID does not change when the user closes and reopens their browser.

With Temporary User IDs stored locally, Relewise is able to connect Temporary IDs and Authenticated IDs via tracking requests. When a user logs into an authenticated user, you should perform a UserUpdate request to immediately link the temporary and the authenticated user together. As a rule, ensure that you use AuthenticatedIDs that are constant, ideally a GUID.


User Classifications

Relewise supports user classifications, which allow you to segment your users without the need for separate datasets.

Segmentation can be done based on any key which is determined to be a good segmentation-key for your customers.

A common example is using the customer's Country as segmentation to better adjust Relewise's personalization, in order to faster understand the country-specific preferences of customers in different countries..

The classification itself is done as part of the user object, and must be included in every behaviour trackings, search request, and recommendation request made to the Relewise API.

Exampleof User Classification

user.Classifications["Country"] = "DK";

We strongly urge you to reach out to us at Relewise to discuss it if you wish to use some type of classification other than country or language. We will be able to help advise you on the best implementation for your site, and help prevent loss of personalization performance due to incorrect implementation.


Events to Track

The strength of Relewise lies in cross-referencing large amounts of data. As such, we recommend setting up as many types of tracking as possible. Below is a list of the tracking types available; use it as a checklist to ensure you have as many of them running as possible.

Click to expand list of Tracking Events
TrackProductViewRequestTracks that a given product has been viewed by a user.
TrackProductCategoryViewRequestTracks that the product list of a given product category has been viewed by a user.
TrackContentViewRequestTracks that a given piece of content has been viewed by a user.
TrackContentCategoryViewRequestTracks that the content list of a given content category has been viewed by a user.
TrackBrandViewRequestTracks that a given brand has been viewed by a user.
TrackCartRequestTracks that a cart has been updated by a user.
TrackOrderRequestTracks that an order has been completed including which products it consisted of.
TrackSearchTermRequestTracks that a user has searched for a given search term.

Note that TrackSearchTermRequest is only applicable if you are not yet using Relewise's search, either because you have yet to implement it or because you have decided to use a different system for now.

Tracking of search terms is useful if you are currently using a different search engine but might switch to Relewise in the future, or if you want to use any of the selected recommendation which operates on search terms inputs, e.g. SearchTermBasedProductRecommendationRequest which allows you to recommend products that other who searched for the same, ended up interacting with during their visit, including products not textually related to the search term provided by the user.

Tracking of search terms is implicitly done automatically when using Relewise Search.

A note on entity IDs

Any entity you want featured in your Relewise experience, whether it be products, content pages, or categories for either, requires an ID for Relewise to track them. These IDs are often frontloaded into Relewise, to allow the engine to warm up with behavioral tracking before the search and recommendation features are activated.

Important Note!

Ensure that you have set up your tracking to correspond with the entity IDs that you have provided to the Relewise API. Discrepancies between IDs means that the behavioral tracking will not function as intended.

In particular, ensure that the Product IDs that you send over match in terms of both Product ID and Variant ID where applicable. Failure to account for the difference between Product and Variant ID can result in the incorrect assumption that variant products are not variants at all, and leads to incorrect and misguiding tracking results.

Another common and critical pitfall is to accidentally send a ProductId as part of a ProductView tracking that differs from the ProductId used in ProductUpdate as part of the product integration. This prevents Relewise from correctly tracking the ID, and in turn keep us from returning the best results for future requests.

4. Recommendation Requests

With Tracking set up and your entities populated, it is time to enable your services. Note that this section is only relevant if you intend to use Relewise for you recommendation sliders.

Best Practice for Recommendation Requests

A recommendation requires two things, namely a User and a Recommendation Type. However, we recommend that you include a Location in your requests as well. Providing a location in your requests will allow you to better track the performance of individual recommendation titles, based on the combined key of RecommendationType + Location + Currency.

Recommendation Types

Relewise offers a host of different recommendation types to improve the experience for your customers, and contribute to better cross and upsale on your website. You can find a full list of them here, and we urge you to familiarize yourself with them so you are fully capable of integrating the ones that are speficially useful for your business. We have nonetheless outlined some of the more popular and universally useful ones for ease of access and to provide you with a best practice for setting up your first recommendations.

You are also welcome to reach out to us for confirmation or guidance on which recommendations are likely to perform the best in your specific case.

Click to expand Recommendation Types by Location
LocationRecommended Request TypeDescription
Front PagePopularProductsShows the most popular products for a given time period, based on most views and most purchases.
Product Details PageProductsViewedAfterProductIncrease conversion rate by showing products that other users have navigated to after not putting the current one in the basket.
Product Details PagePurchasedWithProductIncrease basket sizes by showing other products often purchased together with the current one.
Shows products purchased with one or more of the products currently added to the basket. You can read about the distinction between the two recommendation types here.
Power StepPurchasedWithProductIncrease basket sizes by showing other products often purchased together with the current one.

5. Configuring the Search Index

With entities imported, it is time to set up the search index. This is most easily done via the interface. For more information on the basic functions of the Search Index, click here

Note that this section is only relevant if you intend on using Relewise Search on your website.

Best Practice for Search Index

When you are setting up your Relewise, you will be given a Default search index to work with. It is very important that you engage with it and set it up to your requirements; by default, the index will only search for Product Titles and nothing else, so you must curate it to your specifications.

By default, Relewise provides you with one search index for you to configure. In the vast majority of cases, this is sufficient to give you the control you need, even with multiple languages to configure. If, however, you find that you require more than one search index, we urge you to reach out to us and discuss the possibilities of having another index added to your administration.

Site Coverage Checklist

Since the default Index will only search in Products, and only for Product Title, it is important that you ask yourself the following questions:

  1. Does my search need to find products? If yes, make sure you configure the Product section of the Index.
  2. Does my search need to find product variants? If yes, make sure you configure the Product Variants section of the Index.
    • Relewise treats Products and Product Variants as different entities, which means that you must set up both in the Search Index for your variants to be properly searchable.
  3. Does my search need to find product categories? If yes, make sure you configure the Product Categories section of the Index. Note that there is a distinction between "finding product categories", and "finding products based on their categories". To find products based on their categories, configure the Products section of your Search Index to include Product Category as a weighted field.
  4. Does my search need to find Content Pages? If yes, make sure you configure the Content section of the Index.

Best Practice Search Index

An example of Product Variant fields in the Search Index

Being ISO 639_1 Compliant

Relewise requires langauge codes to conform to the ISO639-1 standard (eg. en or da). The Search Index allows you to configure the language code to fit the ISO standard, provided your data import is not set up for ISO compliancy already. While the field marked ISO639_1 accepts both neutral language strings (en) as well as specific culture codes (en-gb), Relewise only requires the neutral language code.

Best Practices Language Code

The Search Index allows you to link language code and ISO code together

Weighting the Search Index

Search weighting is entirely dependent on what you need from the search engine. As such, this is meant as a jumping-off point for further customization.

Weighting the Search Index - Products

Depending on whether or not you use variants for your products, the best practice for configuring search term weight differs. The important thing to keep in mind is that for search weighting, a higher score means more prominence in the search results.

Generally, the more distinct and less likely a field is to contain anyting not directly relevant to the entity, the higher a weight it should be given. For instance, DisplayName and Brand are candidates for higher weights, where longer texts such as Descriptions are often best configured with a very low weight, since they are more likely to also contain words not specific to the individual entity.

You can read more about the particulars of search weighting here.

If your products do not have variants, focus your weighting on DisplayName first, followed by either CategoryDisplayName or BrandDisplayName. These are almost universally what users are likely to search for, and provides excellent coverage until you are ready to specialize your search weighting further. Set the weight of any field that contains a lot of text (such as a description field) to 1, to ensure that it is searchable without cluttering up the results.

If your products do have variants, your focus will naturally shift towards the particular features of your products. Variant data will vary depending on product type, and so your goal is to promote the most prominent of the data that users will likely search for.

It is important that you differentiate between cases where you need your search function to look for products, and where you need to look for variants. Businesses that operate heavily with variants on the products will see a reduced efficiency of Relewise if this is not implemented correctly.

Weighting the Search Index - Content Pages and Categories

Following the principles above, weighting content pages and content/product categories is straightforward. DisplayName and CategoryDisplayName are highest priority for content, and you may add an additional data key to allow for searching in the main body of text of the content page as well.

Product Category searches should focus on DisplayName, with ID second.

Prediction Source Types

The final stage of configuring your search index is ensuring that each searchable field is parsed correctly by the search engine. Not every field should be engaged with in the same way, which is where prediction source types come in. You can read about the different prediction types here.

Keep in mind that Prediction Source Types affects regular search requests as well as predictive searches/typeahead.

Best practice for prediction source types is to consider the type of field, and the type of data in it. For fields where you only want to predict completions of the the current word, this could be for SKU, ID, or Description fields, use "Individual Words".

For custom fields where you would like Relewise to predict continuations of additional words, like DisplayName use "Partial Word Sequence".

If you dont have a lot of products in your catalog, and would like to predict full sentences based on only a few key strokes, you could consider to configure fields like DisplayName as "Complete Word Sequence", this will instruct Relewise to predict full product names.

Most often, you will only be using "Individual words" and "Partial Word Sequence" in your index, but when suitable, the other options can bring great value given the right use case.

6. Making Search Requests

The final part of your Relewise setup involves preparing your search requests. Note that this is only relevant if you intend on using Relewise Search on your website.

Best Practice for Making Search Requests

Relewise search falls into four request types: ProductSearch, ProductCategorySearch, ContentSearch, and SearchTermPrediction.

A request type contains the following:

  • A Search Term
  • A Language
  • A Currency
  • A User
  • A skip value and a take value (or .pagination if using Javascript/Typescript)

Search requests can also take a Location, and we recommend using locations for your site when possible, to improve your analytics overview.

For good examples and a showcase on how to format and implement search requests, refer to our Examples Page.


Sorting Searches

As a rule of thumb, you do not want to sort the search results until after they have been presented to the user. The default search sorting is built around the personalization that Relewise has gathered for the user, and will produce the best results in the vast majority of cases.

For post-hoc search sorting, make sure to enable a secondary sorting type of relevant, to ensure that sorted results with the same value are given a fallback criterion. For instance, if the user sorts by price, there may be several products with the same price being presented. Having a fallback ThenBy sort type of Relevance, ensures that Relewise always returns the best results first, increasing the likelhood of a conversion, and giving the customer the best possible experience.

Search Refinement

Relewise Search comes pre-equipped with processes for stemming, decompounding, synonyms. That means that most of the common cases are already covered by the Relewise engine, but there may be industry-specific terms that the default settings do not cover.

The UI makes it easy to set up customizations for stemming, decompounding and synonyms, and we recommend that you consider whether there are any particular cases unique to your business where any of these functions might benefit you. You can read more about stemming, decompounding and synonyms in our documentation.

A note about Language

As noted above regarding Multilingual Properties, we urge you to employ Multilingual / MultilingualCollection properties for all data fields containing language-specific texts which you want your users to be searching for. The above features of stemming, decompounding, synonyms etc. will also perform the best when the language of the text in a given field is known. Even if you only have a single language on your site, employ Multilingual poperties whenever a field should be externally searchable and the field contains language-specific text.

Don't know us? Don't worry - you can find more information about us, by visiting our main page