React Native V2.1.X

Introduction

SDK overview

Welcome to the Flagship React Native SDK documentation!

The following documentation helps you to run Flagship on your React Native environment.

Flagship React Native SDK provides a <FlagshipProvider />, which makes Flagship features available to the rest of your app.
Flagship features are accessible using Flagship hooks, have a look at the documentation for details.

Feel free to contact us if you have any questions regarding this documentation.

SDK features

This SDK version helps you:

Prerequisites

  • Node.js: version 6.0.0 or later
  • Npm: version 5.2.0 or later
  • React: version 16.8.0 or later (the SDK only supports hooks for now)

Good to know

Getting started

Initialization

There are four steps to follow to get started with the React Native Flagship SDK.

  1. Install the node module
npm install @flagship.io/react-native-sdk
  1. Import the Flagship React provider

In most cases, do this in your App.js file to wrap your entire app with the provider.

import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider>{/* [...] */}</FlagshipProvider>
  </>
);
  1. Initialize the provider

You must at least include the required props like envId, apiKey, visitorData.

NOTE: apiKey is not required for now but will be in next major release!

import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_VISITOR_ID",
        context: {
          // some context
        },
      }}
      enableConsoleLogs={true}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
  1. Use a Flagship hook in a component

In most case, you will get the desired modifications.

import React from "react";
import { useFsModifications } from "@flagship.io/react-native-sdk";

export const MyReactComponent = () => {
  const fsModifications = useFsModifications([
    {
      key: "backgroundColor",
      defaultValue: "green",
      activate: false,
    },
  ]);
  return (
    <View
      style={[
        {
          height: "200px",
          width: "200px",
          backgroundColor: fsModifications.backgroundColor,
        },
      ]}
    >
      {"I'm a square with color=" + fsModifications.backgroundColor}
    </View>
  );
};

API Reference

FlagshipProvider

Here is the full list of props available to use inside the FlagshipProvider React component:

PropsTypeDefaultDescription
envIdstringRequiredYour Flagship environment id
apiKeystringnullIf you want to use the Decision API V2, you must contact the support team so they'll provide you an API Key to authenticate the calls.
You can find the api key of your environment on the Flagship dashboard, in Parameters > Environment & Security.
visitorDataobjectRequiredThis is the data to identify the current visitor using your app
onInitStartfunction():voidnullCallback function called when the SDK starts initialization
onInitDonefunction():voidnullCallback function called when the SDK ends initialization
onUpdatefunction(object):voidnullCallback function called when the SDK is updated. For example, after a synchronize is triggered or visitor context has changed
onBucketingSuccessfunction(object):voidnullCallback function called when the bucketing polling succeed
onBucketingFailfunction(object):voidnullCallback function called when the bucketing polling failed
initialModificationsArray(object)undefinedThis is an array of modifications where each element must be same shape as the element inside the "campaigns" attribute. Providing this prop prevents the SDK from having an empty cache when it first initializes. If the shape of an element is not correct, an error log will give the reason why
initialBucketingArray(object)undefinedThis is an object of the data received when fetching bucketing endpoint.
Providing this prop will make bucketing ready to use and the first polling will immediatly check for an update.
If the shape of an element is not correct, an error log will give the reason why.
loadingComponentReact.ReactNodeundefinedThis component will be rendered when Flagship is loading at first initialization only. By default, the value is undefined. It means it will display your app and it might display default modifications value for a very short moment.
fetchNowbooleantrueDecide to fetch automatically modifications when SDK is initialized.
NOTE: When fetchNow=false the property loadingComponent will be ignored
activateNowbooleanfalseEnable it to display logs on the console when SDK is running. This will only display logs such as Warnings, Errors, Fatal errors and Info.
enableSafeModebooleanfalseEnable it to run the SDK into a safe mode when an error might occurs through the SDK. When safe mode is triggered, default modifications will be returned and other function will just be executed without doing anything. NOTE: This feature is currently catching errors globally (SDK + your app) which might leads to unexpected SDK safe mode if the error comes from your app. We're working on that issue.
enableErrorLayoutbooleanfalseThis is a small layout visible at the bottom of the screen. It is displayed only when an unexpected error occurred in the SDK. By default, it's set to false and if set to true , it will be only visible in a node environment other than production
nodeEnvstring'production'If value is other than production , it will also display Debug logs.
flagshipApistring'https://decision-api.flagship.io/v1/'This setting can be useful if you need to simulate the API for tests such as end-to-end or if you want to move to an earlier version of the Flagship API. Decision API V1 is set by default but deprecated, starting next version, only Decision API V2 will be implemnented.
decisionMode'API' | 'Bucketing''API'Indicates the behavior of the SDK.
In "API" mode, it will get the modifications using the Flagship decision API.With "Bucketing", it will load all campaigns once and compute the variation assignment of the visitor locally.
Note: When "Bucketing" mode is set, you must specify pollingInterval attribute as well, so that bucketing can check for updates.
Note2: Bucketing mode only works when you allow to start it during SDK initialization (fetchNow=true). We will add the ability to trigger it manually in the next minor release.
pollingIntervalnumbernullIndicates the polling interval period in seconds when SDK is running Bucketing mode (decisionMode="Bucketing").
For example, if pollingInterval=5, a bucketing call will be trigger in background every 5 seconds.
Note1: pollingInterval can't be lower than 1 second.
Note2: if bucketing is enabled and pollingInterval value is null, the polling will be done once and an error log will be trigger.
timeoutnumber2Indicates the delay in seconds before it triggers a timeout when requesting campaigns via the Flagship decision api.
Note: timeout can't be lower than 0 second.

📘

When bucketing is running (decisionMode="Bucketing"), the polling will restart its interval period based on the moment when one of the following props changes after first rendering :

  • envId
  • visitorData
  • initialModifications
  • initialBucketing
  • fetchNow
  • activateNow
  • enableConsoleLogs
  • nodeEnv
  • flagshipApi
  • apiKey
  • pollingInterval

visitorData

The visitorData object takes the following arguments:

ArgumentTypeDescription
idstringRequired. Unique identifier for the current user. This can be an ID from your database or a session ID. If no value is passed, the SDK will
automatically generate a unique ID.
NOTE: The visitor id must be a string and can't be number
contextobjectOptional. JSON object of key-value pairs describing the user and device context

onUpdate

The onUpdate object has one argument with the following shape:

Key/PropertyDescription
fsModificationsArray. It contains the last modifications saved in cache.
configObject. The current configuration running on the SDK.

onBucketingSuccess

The onBucketingSuccess object has one argument with the following shape:

Key/PropertyDescription
statusString. Returns either 200 (fresh update) or 304 (no change).
payloadObject. The latest bucketing data received.

onBucketingFail

The onBucketingFail object has one argument with the following shape:

Key/PropertyDescription
errorObject. Returns the error occurred and leads to bucketing polling failure.

useFlagship

Demo:

This is the most used hook from the Flagship React Native SDK. It gives further functionalities such as getting current modifications of your actual visitor, send hit tracking, SDK status...

Returns an object.

useFlagship input

ArgumentTypeDescription
optionsobjectSee description

useFlagship input options

Key/PropertyTypeDescription
modificationsobjectNode param to specify Flagship modifications. See description

useFlagship input options modifications

ArgumentDescription
requestedRequired. An array of objects for each modifications. See description
activateAllOptional. The value is false by default

useFlagship input options modifications requested

ArgumentDescription
keyRequired. The name of the modification.
defaultValueRequired. The default value if no value for this modification is found.
activateOptional.

useFlagship output

Key/PropertyTypeDescription
modificationsobjectAn object where each key is a modification with corresponding value
getModificationInfofunctionReturns a promise with an object containing informations about modification matching the key specified in argument. See description
synchronizeModificationsfunctionUpdates campaigns targeting that match the current visitor context. See description
hitobjectGives you functions to send one or further hits. See description
statusobjectGives you information about SDK current state. See description
startBucketingPollingfunction()Call this function to start the bucketing manually. See description
stopBucketingPollingfunction()Call this function to stop the bucketing manually. See description

useFlagship output getModificationInfo

Full details here

Returns Promise<object | null>. (Typescript: GetModificationInfoOutput)

ArgumentTypeDescription
keystringThe modification key.

useFlagship output synchronizeModifications

Returns Promise<number>.

Full details here

ArgumentTypeDefaultDescription
activateAllModificationsbooleanfalseIf set to true, all modifications will be activated. If set to false (default behavior), none will be activated.

useFlagship output hits

Key/PropertyDescription
sendTakes an object as parameter. The object must follow a hit shape.
sendMultipleTakes an array of object as parameter. Each object must follow a hit shape. You can mix different hit shapes within the array.

useFlagship output status

Key/PropertyDescription
isLoadingIf true, the SDK isn't ready.
lastRefreshDate cast string with ISO format. This is the date corresponding to the most recent moment where modifications were saved in cache.

useFlagship output startBucketingPolling

Key/PropertyDescription
successBoolean. If true means it succeed, false otherwise.
reasonString. A message telling the reason in case of failure.

useFlagship output stopBucketingPolling

Key/PropertyDescription
successBoolean. If true means it succeed, false otherwise.
reasonString. A message telling the reason in case of failure.

useFsModifications

Demo:

The useFsModifications hook gives you the modifications saved in the SDK cache.

📘

If the SDK cache is empty, it will always return modification's default values.

Returns Flagship modifications.

useFsModifications input

ArgumentTypeDefaultDescription
modificationsRequestedArray(object)RequiredList of all modifications you're looking for. See description
activateAllModificationsbooleanfalseIf set to true, all modifications will be activated. If set to false, none will be activated. NOTE: Setting this argument will override the activate attribute set in each element of the modificationsRequested array.

useFsModifications input modificationsRequested

ArgumentDescription
keyRequired. The name of the modification.
defaultValueRequired. The default value if no value for this modification is found.
activateOptional. Determines whether or not the modification is activated (if activateAllModifications is not set).

useFsActivate

Demo:

Returns void.

useFsActivate input

ArgumentTypeDefaultDescription
modificationKeysArray(string)RequiredAn array of modification keys. For each key, a HTTP request will be sent to activate the corresponding modification.
applyEffectScopeArray(string)[]This argument behaves the same way as the second argument in the React.useEffect hook. It will listen for the array values and synchronize if it detects any changes. By default, it is triggered when the component where it's used is first rendered.

Getting modifications

with useFlagship hook (1/3)

Demo:

import { useFlagship } from "@flagship.io/react-native-sdk";

const fsParams = {
  modifications: {
    requested: [
      {
        key: "btnColor",
        defaultValue: "green",
        activate: false,
      },
    ],
  },
};

const {
  modifications: fsModifications,
  status: fsStatus,
  hit: fsHit,
} = useFlagship(fsParams);

with useFsModifications hook

Demo:

import { useFsModifications } from "@flagship.io/react-native-sdk";

const fsModifications = useFsModifications([
  {
    key: "btnColor",
    defaultValue: "green",
    activate: false,
  },
]);

Campaign synchronization

with useFlagship hook (2/3)

Demo:

import { useFlagship } from "@flagship.io/react-sdk";

const { synchronizeModifications } = useFlagship();

return (
  <>
    <Button
      onClick={() => {
        synchronizeModifications(activateAllModifications)
          .then((statusCode) => {
            if (statusCode < 300) {
              // Notify success...
            } else {
              // Notify failure...
            }
          })
          .catch((error) => {
            // Notify error...
          });
      }}
    >
      Trigger a synchronize
    </Button>
  </>
);

Campaign activation

with useFsActivate hook

Demo:

import { useFsActivate } from "@flagship.io/react-native-sdk";

const [toggle, setToggle] = React.useState(false);

useFsActivate(["btnColor", "otherKey1", "otherKey2"], [toggle]); // trigger an activate when "toggle" value change.

// insider render function:

<Button onClick={() => setToggle(!toggle)}>Trigger activate</Button>;

Experience continuity

It might happen that a visitor from your app is not yet recognized and is being authenticated (and recognized) later on...

From there, we provide the ability to ensure that during such transition, your visitor will keep same experience (meaning targetting still the same campaign's variations and thus same modifications).

In order to do a successful experience continuity, we will have to distinguish when the visitor is anonymous or authenticated.

Let's assume basic scenario to understand how things work:

  1. Your visitor arrives on your app for the first time.

As this visitor will be considered as anonymous, we'll not specify a visitor id so that the SDK will a generate automatically one us. You can also specify some visitor context if necessary.

import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null, // or remove this line
        context: {
          // some context
        },
        isAuthenticated: false, //
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);

Whatever how it has been set, the actual visitor id will be what we call its anonymous id.

📘

Be aware that when you do not specify a visitor id, as enableCache is enable by default, the SDK will try to find a previous visitor experience. If so, the new visitor will have the same visitor id as it was during the previous visitor session. From there, no id will be automatically generated.

  1. Your visitor is signing in.

We need to set the value of visitorData.isAuthenticated to true.

Moreover, the visitor id set should be an existing visitor id (that has previously seen specific campaign's modifications) in order to make the experience continuity effective.

import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "AUTHENTICATED_ID",
        context: {
          // some context
        },
        isAuthenticated: true,
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);

This new visitor id is what we call its authenticated id.

The visitor is updated as authenticated, keeping the previous variations from campaigns that are still matched and thus gives you same modifications as before being logged in.

📘

Keep in mind that if the visitor also has its context changed, you might still have changes on modifications as your visitor might target new campaigns.

  1. Your visitor decide to sign out.

We need to set the value of visitorData.isAuthenticated back to false.

If you want to keep the same visitor (anonymous) experience as before, depending on the value of prop enableCache, you'll have to:

  • enableCache=true: the sdk will put back the previous anonymous id
    automatically based on data from cache.
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null,
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
  • enableCache=false: you should specify in
    prop, the same value as you set in step 1.
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_VISITOR_ID", // <--- same value as step 1
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);

If you need a completly brand new visitor experience, you should put a new visitor id in visitorData.id prop instead:

import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_BRAND_NEW_VISITOR_ID", // <--- new value
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);

Hit Tracking

This section helps you track your users in your application and learn how to build hits in order to feed campaign goals. For more information about our measurement protocol, read our Universal Collect documentation.

There are four different types of hits available:

with useFlagship hook (3/3)

Demo:

import { useFlagship } from "@flagship.io/react-native-sdk";

const { hit: fsHit } = useFlagship();

// insider render function:

<Button
  onClick={() => {
    const mockHit = {
      type: "Transaction",
      data: {
        transactionId: "12451342423",
        affiliation: "myAffiliation",
        totalRevenue: 999,
        shippingCost: 888,
        shippingMethod: "DHL",
        currency: "USD",
        taxes: 1234444,
        paymentMethod: "creditCard",
        itemCount: 2,
        couponCode: "myCOUPON",
        documentLocation:
          "http%3A%2F%2Fabtastylab.com%2F60511af14f5e48764b83d36ddb8ece5a%2F",
        pageTitle: "myScreen",
      },
    };
    fsHit.send(mockHit);
  }}
>
  Send a transaction hit
</Button>;

Hit types

Screen

import { useFlagship } from "@flagship.io/react-native-sdk";

const { hit: fsHit } = useFlagship();

<Button
  onClick={() => {
    const mockHit = {
      type: "Screen",
      data: {
        documentLocation:
          "http%3A%2F%2Fabtastylab.com%2F60511af14f5e48764b83d36ddb8ece5a%2F",
        pageTitle: "testScreen",
      },
    };
    fsHit.send(mockHit);
  }}
>
  Send a screen hit
</Button>;
AttributeTypeDescription
documentLocationstringRequired. Specifies the current URL of the page when the hit is sent.
pageTitlestringRequired. Specifies the current name of the page when the hit is sent.

📘

The Screen hit isn't available yet in the Flagship reporting view.

Transaction

AttributeTypeDescription
transactionIdstringRequired. The ID of your transaction.
affiliationstringRequired. The name of the KPI that you will have inside your reporting. Learn more
totalRevenuenumberOptional. Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts.
shippingCostnumberOptional. The total shipping cost of your transaction.
shippingMethodstringOptional. The shipping method for your transaction.
taxesnumberOptional. Specify the total amount of taxes in your transaction.
currencystringOptional. Specify the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.
paymentMethodstringOptional. Specify the payment method used for your transaction.
itemCountnumberOptional. Specify the number of items of your transaction.
couponCodestringOptional. The coupon code associated with the transaction.
documentLocationstringOptional. Specify the current URL of the page when the hit is sent.
pageTitlestringOptional. Specify the current name of the page when the hit is sent.
import { useFlagship } from "@flagship.io/react-native-sdk";

const { hit: fsHit } = useFlagship();

<Button
  onClick={() => {
    const mockHit = {
      type: "Transaction",
      data: {
        transactionId: "12451342423",
        affiliation: "myAffiliation",
        totalRevenue: 999,
        shippingCost: 888,
        shippingMethod: "DHL",
        currency: "USD",
        taxes: 1234444,
        paymentMethod: "creditCard",
        itemCount: 2,
        couponCode: "myCOUPON",
        documentLocation:
          "http%3A%2F%2Fabtastylab.com%2F60511af14f5e48764b83d36ddb8ece5a%2F",
        pageTitle: "myScreen",
      },
    };
    fsHit.send(mockHit);
  }}
>
  Send a transaction hit
</Button>;

Item

AttributeTypeDescription
transactionIdstringRequired. The ID of your transaction.
namestringRequired. The name of your item.
pricenumberOptional. Specifies the price for a single item/unit.
codestringOptional. Specifies the SKU or item code.
categorystringOptional. Specifies the category that the item belongs to.
quantitynumberOptional. Specifies the number of items purchased.
documentLocationstringOptional. Specifies the current URL of the page when the hit is sent.
pageTitlestringOptional. Specifies the current name of the page when the hit is sent.
import { useFlagship } from "@flagship.io/react-native-sdk";

const { hit: fsHit } = useFlagship();

<Button
  onClick={() => {
    const mockHit = {
      type: "Item",
      data: {
        transactionId: "0987654321",
        name: "testItem",
        price: 999,
        code: "testCode",
        category: "testCategory",
        quantity: 123,
        documentLocation:
          "http%3A%2F%2Fabtastylab.com%2F60511af14f5e48764b83d36ddb8ece5a%2F",
        pageTitle: "testItem",
      },
    };
    fsHit.send(mockHit);
  }}
>
  Send a item hit
</Button>;

📘

The Item hit isn't available yet in the Flagship reporting view

Event

AttributeTypeDescription
categorystringRequired. Specifies the category of your event. NOTE: This value must be either 'Action Tracking' or 'User Engagement'.
actionstringRequired. The name of the KPI you will have inside the reporting.
labelstringOptional. Specifies additional description of your event.
valuenumberOptional. Specifies the monetary value associated with an event (e.g. you earn 10 to 100 euros depending on the quality of lead generated). NOTE: this value must be non-negative.
documentLocationstringOptional. Specifies the current URL of the page when the hit is sent.
pageTitlestringOptional. Specifies the current name of the page when the hit is sent.
import { useFlagship } from "@flagship.io/react-native-sdk";

const { hit: fsHit } = useFlagship();

<Button
  onClick={() => {
    const mockHit = {
      type: "Event",
      data: {
        category: "User Engagement",
        action: "signOff",
        label: "Hello world",
        value: 123,
        documentLocation:
          "http%3A%2F%2Fabtastylab.com%2F60511af14f5e48764b83d36ddb8ece5a%2F",
        pageTitle: "testEvent",
      },
    };
    fsHit.send(mockHit);
  }}
>
  Send a event hit
</Button>;

Demos

Following demos illustrate how the SDK is used in practice ☕

Simple Demo

[react-simple-demo]

Advanced Demo

[react-advanced-demo]

Appendix

Release note

Take a look to the Release note.

Contributing

Take a look at the Contributors Guide if you're interested in contributing to the SDK.

License

This Flagship SDK is distributed under the Apache version 2.0 license.