- klaviyo-react-native-sdk
We currently don't have support for expo. This is something we are looking into and should be available in the future.
The Klaviyo React Native SDK allows developers to incorporate Klaviyo analytics and push notification functionality in their React Native applications for Android and iOS. It is a Typescript wrapper (native module bridge) around the native Klaviyo iOS and Android SDKs. For more information on the native SDKs, please see the iOS and Android. repositories. This repo also contains a basic React Native sample app to assist your integration.
The SDK assists in identifying users and tracking user events via the latest Klaviyo Client APIs. To reduce performance overhead, API requests are queued and sent in batches. The queue is persisted to local storage so that data is not lost if the device is offline or the app is terminated.
Once integrated, your marketing team will be able to better understand your app users' needs and send them timely push notifications via FCM (Firebase Cloud Messaging) and APNs (Apple Push Notification Service).
This SDK was developed and tested against React Native 0.73. We are actively testing and expanding support to the latest patch releases of recent minor versions of React Native.
0.68.7+
- We have successfully compiled this SDK on a bare React Native template app down to0.68.7
. Testing is ongoing to verify on older versions.
minSdkVersion
of23+
compileSdkVersion
of34+
- Minimum Deployment Target
13.0+
The Klaviyo React Native SDK is available via NPM. To add it to your project, run the following from your project's root directory:
# Using npm
npm install klaviyo-react-native-sdk
# Using yarn
yarn add klaviyo-react-native-sdk
We have included an example app in this repository for reference of how to integrate with our SDK.
It is primarily intended to give code samples such as how and where to initialize
, implement notification
delegate methods on iOS, and handle an opened notification intent on Android. We've commented the sample app
code to call out key setup steps, search for iOS Installation Step
and Android Installation Step
.
To run the example app:
- Clone this repository
- From the root directory, run
yarn example-setup
. This is an alias that will do the following:- Run
yarn install --immutable
from the root directory - Navigate to the
example
directory and runbundle install
- Navigate to the
example/ios
directory and runbundle exec pod install
- Run
- Android configuration:
- To initialize Klaviyo from the native layer, open
example/android/gradle.properties
and follow the instructions to set yourpublicApiKey
and verifyinitializeKlaviyoFromNative
is enabled. - If you wish to run the Android example app with push/firebase, you'll need to copy a
google-services.json
file intoexample/android/app/src
and update theapplicationId
inapp/build.gradle
to match your application ID. Then, openexample/android/gradle.properties
and follow the instructions to enableuseNativeFirebase
. This is disabled by default because the app will crash on launch without agoogle-services.json
file.
- To initialize Klaviyo from the native layer, open
- From the project's root directory, run
yarn example start
to start the example application. Follow the metro instructions from here, i.e. pressi
to run on iOS ora
to run on Android.
Android installation requirements may vary depending upon your project configuration and other dependencies.
The Klaviyo React Native SDK's build.gradle
file exposes transitive dependencies upon the Klaviyo Android SDK,
so you can import Android Klaviyo SDK references from your Kotlin/Java files without modifying your gradle configuration.
There are no additional installation requirements.
There are no additional installation requirements. Android support is fully tested and verified.
We have successfully compiled the Klaviyo React Native SDK in a bare React Native template app for these versions
with the following modifications to the android/build.gradle
file:
- Set
minSdkVersion=23
- Set
compileSdkVersion=34
See Android Troubleshooting for possible exceptions.
We are actively working to verify compatibility with these versions. If you encounter issues, please file an issue.
After installing the npm package, run the following command in the ios
directory of your React Native project.
Install Cocoapods if you have not already.
pod install
The SDK must be initialized with the short alphanumeric public API key for your Klaviyo account, also known as your Site ID.
Initialize must be called prior to invoking any other SDK methods so that Klaviyo SDK can track profiles, events and push tokens toward the correct Klaviyo account. Any SDK operations invoked before initialize will be dropped, and result in a logged error.
You can call initialize
from your app's React Native layer or from the platform-specific native code.
This decision is dependent on your app's architecture. It is not required to initialize the SDK in both places!
Note: It is safe to re-initialize, e.g. if your app needs to switch between more than one Klaviyo account.
Below is an example of how to initialize the SDK from your React Native code:
import { Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.initialize('YOUR_KLAVIYO_PUBLIC_API_KEY');
Follow the native SDK instructions for initialization, and refer to the example app in this repository for guidance:
- Android SDK instructions, and
example app
MainApplication.kt
- iOS SDK instructions, and
example app
AppDelegate.mm
The SDK provides methods to identify profiles via the Create Client Profile API. A profile can be identified by any combination of the following:
- External ID: A unique identifier used by customers to associate Klaviyo profiles with profiles in an external system, such as a point-of-sale system. Format varies based on the external system.
- Individual's email address
- Individual's phone number in E.164 format
Identifiers are persisted to local storage on each platform so that the SDK can keep track of the current profile.
Profile attributes can be set all at once:
import { Klaviyo, Profile } from 'klaviyo-react-native-sdk';
const profile: Profile = {
email: 'kermit@example.com',
phoneNumber: '+15555555555',
externalId: '12345',
firstName: 'Kermit',
lastName: 'The Frog',
title: 'CEO',
organization: 'Muppets, Inc.',
location: {
address1: '666 Fake St.',
address2: 'Apt 123',
city: 'Cityville',
country: 'Countryland',
region: 'Regionville',
zip: '11111',
},
};
Klaviyo.setProfile(profile);
or individually:
import { ProfilePropertyKey, Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.setEmail('kermit@example.com');
Klaviyo.setPhone('+15555555555');
Klaviyo.setExternalId('12345');
Klaviyo.setProfileAttribute(ProfilePropertyKey.FIRST_NAME, 'Kermit');
Either way, the native SDKs will group and batch API calls to improve performance.
To start a new profile altogether (e.g. if a user logs out), either call Klaviyo.resetProfile()
to clear the currently tracked profile identifiers (e.g. on logout), or use Klaviyo.setProfile(profile)
to overwrite it with a new profile object.
import { Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.resetProfile();
Klaviyo will track unidentified users with an autogenerated ID whenever a push token is set or an event is created. That way, you can collect push tokens and track events prior to collecting profile identifiers such as email or phone number. When an identifier is provided, Klaviyo will merge the anonymous user with an identified user.
The SDK also provides tools for tracking analytics events via the
Create Client Event API.
A list of common Klaviyo-defined event metrics is provided in MetricName
,
or you can just provide a string for a custom event name.
Below is an example using one of the Klaviyo-defined event names:
import { Event, Klaviyo, EventName } from 'klaviyo-react-native-sdk';
const event: Event = {
name: EventName.STARTED_CHECKOUT_METRIC,
value: 99,
properties: { products: ['SKU1', 'SKU2'] },
};
Klaviyo.createEvent(event);
You can also create an event by providing a string for the event name as follows:
import { Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.createEvent({
name: 'My Custom Event',
});
Integrating push notifications is highly platform-specific. Begin by thoroughly reviewing the setup instructions for Push Notifications in the README from each native Klaviyo SDK:
Refer to the following README sections on push setup:
Push tokens can be collected either from your app's react native code or in the native code. Below sections discuss both approaches, and you are free to pick one that best suits your app's architecture. Note that doing this in one location is sufficient.
In order to collect the APNs push token in your React Native code you need to:
-
Import a library such as
@react-native-firebase/messaging
to your react native project. The below instructions are specific for@react-native-firebase/messaging
library. -
Import Firebase iOS SDK to your iOS project. Setup instructions can be found here.
-
In order for the
UNUserNotificationCenter
delegate methods to be called inAppDelegate
, method swizzling must be disabled for the Firebase SDK. For more information on this, please refer to the Firebase documentation. Disable method swizzling by adding the following to yourInfo.plist
:<key>FirebaseAppDelegateProxyEnabled</key> <false/>
-
In
application:didRegisterForRemoteNotificationsWithDeviceToken:
method in yourAppDelegate.m
file, you can add the following code to set the push token to the firebase SDK:// since we disbaled swizzling, we have to manually set this FIRMessaging.messaging.APNSToken = deviceToken;
-
Finally, in your React Native code, you can collect & set the push token as follows:
import messaging from '@react-native-firebase/messaging'; import { Klaviyo } from 'klaviyo-react-native-sdk'; import { Platform } from 'react-native'; const fetchAndSetPushToken = async () => { try { let deviceToken: string | null = null; if (Platform.OS === 'android') { // For Android, Klaviyo requires the FCM token deviceToken = await messaging().getToken(); console.log('FCM Token:', deviceToken); } else if (Platform.OS === 'ios') { // For iOS, Klaviyo requires the APNs token deviceToken = await messaging().getAPNSToken(); console.log('APNs Token:', deviceToken); } if (deviceToken != null && deviceToken.length > 0) { Klaviyo.setPushToken(deviceToken!); } } catch (error) { console.error('Error in fetchAndSetPushToken:', error); } };
For Android token collection, there isn't any additional setup required on the native side. The above code should work as is.
Follow the platform-specific instructions below:
Requesting user permission to display notifications can be managed from the React Native code, or from platform-specific native code. Note that either of these approaches is sufficient to inform the Klaviyo SDK of the permission change.
-
React Native Notification Permission: You can leverage a third party library that provides cross-platform permissions APIs like firebase
react-native-firebase/messaging
. If you opt for a cross-platform permission solution, call the Klaviyo React Native SDK'ssetToken
method to refresh the token's enablement status.Below is an example of how to use
@react-native-firebase/messaging
to request permission and set the token:import messaging from '@react-native-firebase/messaging'; const requestUserPermission = async () => { let isAuthorized = false; if (Platform.OS === 'android') { const androidAuthStatus = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS ); isAuthorized = androidAuthStatus === 'granted'; } else if (Platform.OS === 'ios') { const iOsAuthStatus = await messaging().requestPermission(); isAuthorized = iOsAuthStatus === messaging.AuthorizationStatus.AUTHORIZED || iOsAuthStatus === messaging.AuthorizationStatus.PROVISIONAL; } // refer the `fetchAndSetPushToken` method from the previous section for how to get and set the push token if (isAuthorized) { console.log('User has notification permissions enabled.'); } else { console.log('User has notification permissions disabled'); } };
-
Native Notification Permission: Follow instructions from our native SDK documentation to request permission from native code:
If you requested permission using native code then continue using Klaviyo's native platform SDKs
setToken
method to inform the SDK of permission change.
You can send test notifications to a specific token using the push notification preview feature in order to test your integration.
Rich Push is the ability to add images to push notification messages. On iOS, you will need to implement an extension service to attach images to notifications. No additional setup is needed to support rich push on Android.
Klaviyo tracks push opens events with a specially formatted event Opened Push
that includes message tracking
parameters in the event properties. To track push opens, you will need to follow platform-specific instructions.
Currently, tracking push open events must be done from the native code due to platform differences that prevent
us from bridging this functionality into the React Native SDK code.
Note: If you initialize Klaviyo from React Native code, be aware that on both platforms the timing of when an
Opened Push
event gets triggered can sometimes occur before your React Native code to initialize our SDK can execute. To mitigate this, our SDK holds the request in memory until initialization occurs.
Deep Links allow you to navigate to a particular page within your app in response to the user opening a notification. Familiarize yourself with the React Native Guide to deep linking, then read through the platform-specific instructions below.
-
Android instructions for handling intent filters
-
iOS As shown in the native SDK documentation, you can follow option 1 or 2.
With option 1, when you handle the open url (in
application(_:open:options)
), you call the linking code block above similar to what you would do with option 1.With option 2, when you get the
deepLinkHandler
, you can handle it as follows:[RCTLinkingManager application:UIApplication.sharedApplication openURL: url options: @{}];
For application, you can pass in an instance of
UIApplication
and since you won't haveoptions
, you can just pass in an empty dictionary for that parameter.
In your React Native code, you can handle the deep link as follows:
import { Linking } from 'react-native';
Linking.addEventListener('url', (event) => {
console.log(event.url);
});
Linking.getInitialURL().then((url) => {
console.log('Initial Url: url', url);
});
Use the troubleshooting guide to resolve common issues with the Klaviyo React Native SDK. If the issues you are facing isn't in the troubleshooting guide, and you believe it's a bug in the SDK, please file an issue in our repository.
Refer to the contributing guide to learn how to contribute to the Klaviyo React Native SDK. We welcome your feedback in the issues section of our public GitHub repository.
The Klaviyo React Native SDK is available under the terms of the MIT license. See LICENSE for more info.
Browse complete autogenerated code documentation here.