Skip to content
Login Contact

React Native SDK setup, tracking, and API reference

We also offer a sample playground application to demonstrate how our SDK can be used. You can access the GitHub repository here: React Native Example Application

Install the package from npm:

npm install @marfeel/react-native-sdk

Add the following repository to your app-level android/build.gradle file:

allprojects {
repositories {
google()
mavenCentral()
maven {
url "https://repositories.mrf.io/nexus/repository/mvn-marfeel-public/"
}
}
}

Install the CocoaPods dependencies:

cd ios && pod install

No additional configuration is required. The native SDK is installed automatically via CocoaPods.

To begin tracking, initialize the SDK using the initialize method and provide your unique Marfeel Account Id:

import { CompassTracking } from '@marfeel/react-native-sdk';
CompassTracking.initialize('/* AccountId */');
Simply replace the /* AccountId */ placeholder with your Marfeel Account ID.
All SDK initialization calls (initialize, setLandingPage, trackScreen) must happen in the same top-level useEffect. Child component effects fire before parent effects in React Native, so spreading these calls across components may cause them to execute before initialization completes.
import React, { useEffect } from 'react';
import { CompassTracking } from '@marfeel/react-native-sdk';
export default function App() {
useEffect(() => {
CompassTracking.initialize('/* AccountId */');
CompassTracking.setLandingPage('https://example.com/');
CompassTracking.trackScreen('home');
}, []);
return (/* your app */);
}

The default value for the Page Technology dimension depends on the underlying platform (iOS App or Android App). However, you can modify this default value using the pageTechnology parameter:

CompassTracking.initialize('/* AccountId */', 105);
Custom Page Technologies have IDs above 100 and must be declared on the Organization Settings

To utilize the library, import the CompassTracking class from the package.

import { CompassTracking } from '@marfeel/react-native-sdk';

All tracking features are available as static methods on the CompassTracking object.

CompassTracking automatically monitors user time on a page. When a user begins reading a new page, you should provide the page’s canonical URL.

CompassTracking.trackNewPage('https://example.com/article');
CompassTracking.trackNewPage('https://example.com/article', { rs: 'homepage' });

In cases where you can’t provide the canonical URL you can use the Editorial Metadata API.

CompassTracking will continue tracking reading time until the trackNewPage method is called again with a different URL or until you explicitly invoke the stopTracking() method.

CompassTracking.stopTracking();

If you want to track a screen instead of a new page, particularly when your view doesn’t have a real URI, you can utilize the trackScreen method. This method accepts a raw name instead of an actual URI for tracking purposes.

CompassTracking.trackScreen('profile');
CompassTracking.trackScreen('profile', { rs: 'menu' });

If you want to inform about the landing page of the session, use the following method:

CompassTracking.setLandingPage('https://example.com/');

If you want to include UTMs, you’ll need to add them to the landing page.

The SDK provides CompassScrollView, a component that wraps React Native’s ScrollView and automatically tracks scroll depth:

import { CompassScrollView } from '@marfeel/react-native-sdk';
<CompassScrollView>
{/* Your scrollable content */}
</CompassScrollView>

CompassScrollView supports the same props as ScrollView, and can also wrap FlatList or SectionList using the as prop:

<CompassScrollView
padding={16}
showsVerticalScrollIndicator={false}
>
{/* Your scrollable content */}
</CompassScrollView>
import { FlatList } from 'react-native';
<CompassScrollView as={FlatList} data={items} renderItem={renderItem} />
import { SectionList } from 'react-native';
<CompassScrollView as={SectionList} sections={sections} renderItem={renderItem} />

You can also report scroll percentage manually:

CompassTracking.updateScrollPercentage(75);

To associate the app user to the records generated by the library, use the setSiteUserId method, indicating the user ID in your platform.

CompassTracking.setSiteUserId('user_123');

On the other hand, if you need to retrieve marfeel user id for forwarding it to one of our apis, the method you need to use is getUserId()

const userId = await CompassTracking.getUserId();

You can specify the type of user with the options below. By default, if not specified, the user will be tracked as Anonymous.

import { CompassTracking, UserType } from '@marfeel/react-native-sdk';
CompassTracking.setUserType(UserType.Anonymous);
CompassTracking.setUserType(UserType.Logged);
CompassTracking.setUserType(UserType.Paid);
CompassTracking.setUserType({ custom: 8 });
TIP:
It's recommended to first provide the user ID and the user journey information before initiating the tracking of the first pageview.

If you want to access the RFV of the user within a session, you can retrieve it using the getRFV method.

const rfv = await CompassTracking.getRFV();
if (rfv) {
// RFV object containing:
// - rfv (number): The composite RFV score representing overall user engagement.
// - r (number): Recency — how recently the user has visited.
// - f (number): Frequency — how often the user visits.
// - v (number): Volume — how much content the user consumes.
}

You can track conversions calling the trackConversion() method:

CompassTracking.trackConversion('subscription');

Just like in web, Conversion parameters are available for Native

import { ConversionScope } from '@marfeel/react-native-sdk';
CompassTracking.trackConversion('purchase', {
id: 'order_123', // each pair {CONVERSION} and {ID} will only be tracked once
value: '29.99',
meta: { currency: 'EUR', plan: 'annual' },
scope: ConversionScope.Page, // Page | Session | User
});

Keep in mind that trackConversion with the same conversion and options.id will only be tracked once.

In the following example, if you send the first call:

CompassTracking.trackConversion('conv_1', {
id: 'id_1',
value: '3',
});

A second call won’t be tracked because conv_1:id_1 has already been tracked:

CompassTracking.trackConversion('conv_1', {
id: 'id_1',
value: '4',
});

In order to mark if the current visit has consent approved or not, sdk offers the following method to use:

CompassTracking.setConsent(true);

User data will be deleted each time the user closes the app if no consent is provided.

CompassTracking.setPageVar('category', 'technology');
CompassTracking.setSessionVar('theme', 'dark');
CompassTracking.setUserVar('preferredLanguage', 'en');

Adds a new persistent user segment

CompassTracking.addUserSegment('premium');

Replaces existing user segments

CompassTracking.setUserSegments(['premium', 'newsletter']);

Removes existing user segment

CompassTracking.removeUserSegment('newsletter');

Clears all user segments

CompassTracking.clearUserSegments();
CompassTracking.setPageMetric('wordCount', 1200);
Only integer values are accepted

All multimedia tracking features are available as static methods on the MultimediaTracking object.

import { MultimediaTracking } from '@marfeel/react-native-sdk';
import { MultimediaType, MultimediaEvent } from '@marfeel/react-native-sdk';
import type { MultimediaMetadata } from '@marfeel/react-native-sdk';
enum MultimediaType {
Audio = 'audio',
Video = 'video',
}
enum MultimediaEvent {
Play = 'play',
Pause = 'pause',
End = 'end',
UpdateCurrentTime = 'updateCurrentTime',
AdPlay = 'adPlay',
Mute = 'mute',
Unmute = 'unmute',
FullScreen = 'fullscreen',
BackScreen = 'backscreen',
EnterViewport = 'enterViewport',
LeaveViewport = 'leaveViewport',
}
interface MultimediaMetadata {
isLive?: boolean;
title?: string;
description?: string;
url?: string;
thumbnail?: string;
authors?: string;
publishTime?: number;
duration?: number;
}
Note:
For the full list of available events (MultimediaEvent) and media types (MultimediaType), refer to the Multimedia tracking documentation.
import { MultimediaTracking, MultimediaType } from '@marfeel/react-native-sdk';
MultimediaTracking.initializeItem(
'videoId', // id (mandatory)
'youtube', // provider (mandatory)
'youtube-video-id', // providerId (mandatory)
MultimediaType.Video, // type (mandatory)
{ // metadata (optional)
title: 'Video Title',
description: 'Video description',
url: 'https://youtube.com/watch?v=youtube-video-id',
authors: 'John Doe',
duration: 420,
}
);
import { MultimediaTracking, MultimediaEvent } from '@marfeel/react-native-sdk';
MultimediaTracking.registerEvent('videoId', MultimediaEvent.UpdateCurrentTime, 150);

Track which elements in your app are shown, visible, and clicked. Works for any element you need to measure: recommendation modules, banners, CTAs, or anything else. The SDK reports eligibility, visibility, and clicks; your app decides what those elements are.

import { Recirculation } from '@marfeel/react-native-sdk';
Working example: see ExperiencesScreen.tsx in the demo app for a complete recirculation tracking flow.

Represents a single trackable element within a module:

PropertyTypeDescription
urlstringCanonical URL of the element’s destination
positionnumberZero-based position of the element within the module
interface RecirculationLink {
url: string;
position: number;
}

Each module must be tracked through its full lifecycle:

MethodWhen to call
trackEligibleThe module has been selected and will appear in the current page view
trackImpressionOne or more elements become visible on screen
trackClickThe user taps an element within the module
import { Recirculation } from '@marfeel/react-native-sdk';
const moduleName = 'example-module-name';
const links = [
{ url: 'https://example.com/article-1', position: 0 },
{ url: 'https://example.com/article-2', position: 1 },
{ url: 'https://example.com/article-3', position: 2 },
];
Recirculation.trackEligible(moduleName, links);
Recirculation.trackImpression(moduleName, [links[0], links[1]]);
Recirculation.trackImpression(moduleName, links[2]);
Recirculation.trackClick(moduleName, links[1]);
All recirculation methods are fire-and-forget. The SDK dispatches on a background thread on the native side and silently ignores failures.

The Experiences API lets you fetch experiences configured in Experience Manager for the current page so your app can render them. You can filter by type or family, resolve remote content on demand, and track user interactions. The SDK returns the configuration; rendering is the app’s responsibility.

All experiences features are made available through the Experiences module:

import { Experiences } from '@marfeel/react-native-sdk';
Working example: see ExperiencesScreen.tsx in the demo app for a complete experiences fetch and tracking flow.

Fetch experiences for the current targeting using fetchExperiences. The SDK automatically uses the URL from the active page being tracked. This is an async function that returns a Promise<Experience[]>.

import { Experiences } from '@marfeel/react-native-sdk';
const result = await Experiences.fetchExperiences();
fetchExperiences requires the SDK to be initialized via CompassTracking.initialize() and a page to be actively tracked via trackNewPage or trackScreen. If no page is being tracked, an empty list is returned.

Each Experience contains:

PropertyTypeDescription
idstringUnique experience identifier
namestringExperience name from the server configuration
typeExperienceTypeExperience type (Inline, Flowcards, Compass, AdManager, etc.)
familyExperienceFamily | nullOptional experience family (Recommender, Paywall, Widget, etc.). Null when not specified by the server
placementstring | nullPlacement identifier
contentUrlstring | nullURL to fetch the experience content from
contentTypeExperienceContentTypeContent type (TextHTML, Json, AMP, etc.)
featuresRecord<string, unknown> | nullArbitrary feature flags and configuration
strategystring | nullPlacement strategy (e.g., replace, append)
resolvedContentstring | nullThe fetched content body, populated after calling resolveContent() or when resolve: true
rawJsonRecord<string, unknown>The full original JSON for accessing fields not explicitly modeled

You can filter experiences by type, family, or both:

import {
Experiences,
ExperienceType,
ExperienceFamily,
} from '@marfeel/react-native-sdk';
// Filter by type
const inlineOnly = await Experiences.fetchExperiences({
filterByType: ExperienceType.Inline,
});
// Filter by family
const recommenders = await Experiences.fetchExperiences({
filterByFamily: ExperienceFamily.Recommender,
});
// Combine both filters (AND logic)
const inlineRecommenders = await Experiences.fetchExperiences({
filterByType: ExperienceType.Inline,
filterByFamily: ExperienceFamily.Recommender,
});

Available experience families:

Enum ValueServer Key
Twittertwitterexperience
Facebookfacebookexperience
Youtubeyoutubeexperience
Recommenderrecommenderexperience
Telegramtelegramexperience
Gatheringgatheringexperience
Affiliateaffiliateexperience
Podcastpodcastexperience
Experimentationexperimentsexperience
Widgetwidgetexperience
MarfeelPasspassexperience
Scriptscriptexperience
Paywallpaywallexperience
MarfeelSocialmarfeelsocial
The Server Key is the raw string value returned by the server in the family field. Use it when accessing rawJson directly or when debugging API responses. When the server returns an unrecognized value, it maps to ExperienceFamily.Unknown. When the field is absent, it is null.

By default, fetchExperiences does not resolve content. You can enable automatic resolution for all experiences that have a contentUrl, or resolve individually on demand:

import { Experiences } from '@marfeel/react-native-sdk';
// No content resolution (default)
const result = await Experiences.fetchExperiences();
result[0].resolvedContent; // null
// Resolve all content automatically
const resolved = await Experiences.fetchExperiences({ resolve: true });
resolved[0].resolvedContent; // contains the fetched content
// Resolve individually on demand
const list = await Experiences.fetchExperiences();
const content = await Experiences.resolveContent(list[0]);

Add custom targeting key-value pairs that will be sent with every experiences request:

Experiences.addTargeting('key', 'value');

Each experience that your app consumes must be tracked through its full lifecycle. Call the appropriate method as each stage occurs. Tracking link interactions uses RecirculationLink, defined in the Recirculation Tracking section above.

MethodWhen to call
trackEligibleThe experience has been selected and is intended to be shown on the current page view
trackImpressionThe experience content has been rendered and is visible to the user
trackClickThe user tapped on a specific link within the experience
trackCloseThe user dismissed or closed the experience
import { Experiences, ExperienceFamily } from '@marfeel/react-native-sdk';
const result = await Experiences.fetchExperiences({
filterByFamily: ExperienceFamily.Recommender,
});
const recommender = result[0];
const links = [
{ url: 'https://example.com/article-1', position: 0 },
{ url: 'https://example.com/article-2', position: 1 },
{ url: 'https://example.com/article-3', position: 2 },
];
// The experience will be used in this page view
Experiences.trackEligible(recommender, links);
// First two links are visible on screen
Experiences.trackImpression(recommender, [links[0], links[1]]);
// After scrolling, the third link becomes visible
Experiences.trackImpression(recommender, links[2]);
// The user tapped a link inside the experience
Experiences.trackClick(recommender, links[1]);
// The user dismissed the experience
Experiences.trackClose(recommender);