Skip to content

Client-side tracking

Relewise has an open source JavaScript SDK which, among other things, will make implementing tracking very easy.
Documentation and installation instructions can be found here: GitHub repository.

The documentation describes implementing tracking, as well as how the different User Types are handled - including topics like GDPR compliance.

To get started with tracking, we need to start by making a Tracker-instance.

ts
const tracker = new Tracker(RELEWISE_DATASET_ID, RELEWISE_API_KEY, {
    serverUrl: RELEWISE_SERVER_URL,
});

Before going any further, make sure you have read about how to authenticate against our API here.

UserFactory

In order to provide the best user experience with personalization, it is important that users who give permission to be tracked (marketing cookies) are tracked with a unique ID. This unique ID can be advantageously accessed through your cookie consent supplier.

User Classifications

If there is a logical segmentation of users, e.g. country, provide this segmentation via a collection of key/value pairs as described below. To learn more about classifications, click here.

ts
const classifications: Record<string, string> = {
    'Country': 'DA',
};
UserFactory.anonymous({ classifications });
UserFactory.byTemporaryId("tempId", { classifications });

It is recommended to seek advice from Relewise before introducing segmentation by Classifications. Incorrect/excessive usage will potentially yield worse recommendations and search results.

Channels

It is possible to provide a channel as part of the User-object, which is used in MyRelewise to filter the data received via the API. If you, e.g., have a website and one or more apps, you can provide information about what channel the user is using. Below are some examples of providing a channel for a Website and 2 different apps:

Website user

ts
const channel: Channel = {
    name: 'Website'
};
const user = UserFactory.anonymous();

user.channel = channel;

Android App

ts
const channel: Channel = {
    name: 'App',
    subChannel: { name: 'Android' }
};
const user = UserFactory.anonymous();

user.channel = channel;

iOS App

ts
const channel: Channel = {
    name: 'App',
    subChannel: { name: 'iOS' }
};
const user = UserFactory.anonymous();

user.channel = channel;

Here is a list of commonly used cookie consent providers. These examples can be used as a baseline on how to create the correct user, based on the user's cookie consent permissions. You will need to add channel and classifications based on your own usecases to these examples.

Cookiebot example

ts
function getUser() {
    return window.CookieConsent && 
           window.CookieConsent.consent && 
           window.CookieConsent.consent.marketing && 
           window.CookieConsent.consentID !== '0'
        ? UserFactory.byTemporaryId(window.CookieConsent.consentID)
        : UserFactory.anonymous();
};

CookieInformation example

ts
function getUser() {
    return window.CookieInformation && 
           window.CookieInformation.getConsentGivenFor('cookie_cat_marketing')
        ? UserFactory.byTemporaryId(CookieInformation._getVisitorId())
        : UserFactory.anonymous();
};

CookieScript example

ts
function getUser() {
    return window.CookieScript && 
           window.CookieScript.instance.currentState().categories.some(x => x === "targeting")
        ? UserFactory.byTemporaryId(window.CookieScript.instance.currentState().key)
        : UserFactory.anonymous();
};

Usercentrics example

ts
function getUser() {
    if (!window.UC_UI) {
        return UserFactory.anonymous();
    }

    const allowMarketingCookies = false;

    const marketingServices = window.UC_UI.getServicesBaseInfo().filter(service => service.categorySlug === 'marketing');

    if (marketingServices.length > 0) {
        allowMarketingCookies = marketingServices.filter(service => service.consent.status === false).length > 0 ? false : true;
    }

    return allowMarketingCookies
        ? UserFactory.byTemporaryId(window.UC_UI.getControllerId())
        : UserFactory.anonymous();
};

Product Details Page (PDP)

On the Product Details Page (PDP), the following code must be called to track a product view:

ts
await tracker.trackProductView({
    productId: 'p-1',
    user: getUser(),
});

Here, the Product Id is sent in, and it's possible to also provide a variant Id as an additional parameter in the method call.

Product Listing Page / Collection Pages (PLP)

On the Product Listing Page (PLP), the following code is called to track a category page view:

ts
await tracker.trackProductCategoryView({
    idPath: ['c1'],
    user: getUser(),
})

Here, the IdPath must contain the unique ID for the current Collection Page.

Cart / Basket updates

In case of any change to the user's basket, the following is called with the full contents of the basket:

ts
await tracker.trackCart({
    lineItems: [
        {
            lineTotal: 100,
            productId: 'p-1',
            quantity: 1,
            variantId: 'v1',
        },
    ],
    subtotal: {
        amount: 100,
        currency: 'DKK', 
    },
    user: getUser(),
})

A note on Cart Name

When tracking a cart, it is not necessary to specify the Name value If you need to track the ID of the cart, such as for the AbandonedCart trigger, Cart ID should not be added as the Name, but instead be added as a Data Field. In this case, Name should be set to default.

Specifying Name is only relevant in the instance where multiple carts need to be tracked simultaneously. For all other cases, Name does not need to be specified, and if you do decide to include it in the request, it should be set to default.

Content Page

On the Content page, the following code is called to track a content page view:

ts
await tracker.trackContentView({
    contentId: 'p-1',
    user: getUser(),
});

Brand Page

On the Brand page, the following code is called to track a brand page view:

ts
await tracker.trackBrandView({
    brandId: '<brand-id>',
    user: getUser(),
});

Orders / Purchases

When a user completes an order / makes a purchase, the following code is called to track an order:

ts
await tracker.trackOrder({
    lineItems: [
        {
            lineTotal: 100,
            productId: 'p-1',
            quantity: 1,
            variantId: 'v1',
        },
    ],
    subtotal: {
        amount: 100,
        currency: 'DKK', 
    },
    orderNumber: '<order-number>',
    user: getUser(),
})

Search Term

When a user performs a search in the search field, the following code is called to track that an search has been performed:

ts
await tracker.trackSearchTerm({
    term: 'term',        
    language: 'da',        
    user: getUser(),    
})

Note: you should only perform this tracking if you are not using Relewise for search. When using Relewise for search, the search term is automatically tracked via the product search API.

User Update

When a user's details change, for example, when the user logs into the webshop or when the user is directed to the webshop through a newsletter, the following code can be called to track that the user has changed:

ts
const user = UserFactory.byAuthenticatedId('<authId>', 'temporaryId', { 
    email: '<user@email.com>', 
    identifiers: {
        '<mail-system-identifier>': '<identifier>',
    }
});

await tracker.trackUserUpdate({
    user: user,
});

Note: you should only perform this tracking, when important user data changes - eg NOT when a users accepts or declines cookies.

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