- klaviyo-react-native-sdk
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).
If you have an Expo app, you can install our plugin to integrate the React Native SDK into your app. See the Klaviyo Expo Plugin for more details.
This SDK was developed and tested against React Native 0.78, as a new-architecture compatible native module.
We support all maintained React Native versions, 0.70+.
We have successfully compiled this SDK on a bare React Native template app down to 0.68.7.
minSdkVersionof23+compileSdkVersionof34+
- 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-sdkWe 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 --immutablefrom the root directory - Navigate to the
exampledirectory and runbundle install - Navigate to the
example/iosdirectory and runbundle exec pod install
- Run
- Android configuration:
- To initialize Klaviyo from the native layer, open
example/android/gradle.propertiesand follow the instructions to set yourpublicApiKeyand verifyinitializeKlaviyoFromNativeis enabled. - If you wish to run the Android example app with push/firebase, you'll need to copy a
google-services.jsonfile intoexample/android/app/srcand update theapplicationIdinapp/build.gradleto match your application ID. Then, openexample/android/gradle.propertiesand follow the instructions to enableuseNativeFirebase. This is disabled by default because the app will crash on launch without agoogle-services.jsonfile.
- To initialize Klaviyo from the native layer, open
- From the project's root directory, use the following commands start a metro server and run the example app.
yarn example start- to start the metro serveryarn example android- to run the example app on an Android emulator or deviceyarn example ios- to run the example app on an iOS simulator
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. 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.
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 installYou may also need to run pod update or pod install --repo-update after updating your SDK version.
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: '[email protected]',
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 { ProfileProperty, Klaviyo } from 'klaviyo-react-native-sdk';
Klaviyo.setEmail('[email protected]');
Klaviyo.setPhone('+15555555555');
Klaviyo.setExternalId('12345');
Klaviyo.setProfileAttribute(ProfileProperty.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/messagingto your react native project. The below instructions are specific for@react-native-firebase/messaginglibrary. -
Import Firebase iOS SDK to your iOS project. Setup instructions can be found here.
-
In order for the
UNUserNotificationCenterdelegate 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.mfile, 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'ssetTokenmethod to refresh the token's enablement status.Below is an example of how to use
@react-native-firebase/messagingto 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
setTokenmethod 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 supports setting or incrementing the badge count on iOS when you send a push notification. To enable this functionality, you will need to implement a notification service extension and app group as detailed in the Swift SDK installation instructions. See the badge count documentation for more details and the example app for reference. Android automatically handles badge counts, and no additional setup is needed.
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 Pushevent 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.
Klaviyo Deep Links allow you to navigate to a particular page within your app in response to the user opening a push notification, tapping on a link in an In-App Form, or by tapping on a Universal Link (aka Verified App Link on Android) from outside of the app. The Klaviyo Android SDK supports deep linking via custom URI schemes or Universal Links.
Familiarize yourself with the React Native Linking Guide, then follow the platform-specific instructions for configuring both custom URL schemes and universal links:
- iOS Deep Linking Setup - Configure custom URL schemes, Associated Domains for Universal Links, and implement the appropriate delegate methods in your AppDelegate
- Android Deep Linking Setup - Configure intent filters for both custom schemes and App Links in your AndroidManifest.xml
In your React Native code, use the Linking API to handle both deep links and universal links. The example below
shows how to integrate with Klaviyo's universal tracking link handling:
import { useEffect } from 'react';
import { Linking } from 'react-native';
import { Klaviyo } from 'klaviyo-react-native-sdk';
export default function App() {
useEffect(() => {
const handleUrl = (url: string) => {
// Check if this is a Klaviyo universal tracking link
if (Klaviyo.handleUniversalTrackingLink(url)) {
// Klaviyo SDK is handling the tracking link
console.log('Klaviyo tracking link:', url);
return;
}
// Handle other deep links in your app (both custom schemes and universal links)
console.log('Navigate to:', url);
// Add your navigation logic here
};
// Handle the initial URL if the app was opened with a link
Linking.getInitialURL().then((url) => {
if (url) {
handleUrl(url);
}
});
// Listen for deep link events while the app is running
const subscription = Linking.addEventListener('url', ({ url }) => {
handleUrl(url);
});
return () => {
subscription.remove();
};
}, []);
// Rest of your app code
}The Klaviyo.handleUniversalTrackingLink() method will:
- Validate that the URL is a Klaviyo tracking link (format:
https://domain/u/...) - Track the click event
- Resolve the tracking link to its destination URL
- Return
trueif it handled the link,falseotherwise
If the link is not a Klaviyo tracking link, you should handle it as a regular deep link in your app.
Silent push notifications (also known as background pushes) allow your app to receive payloads from Klaviyo without displaying a visible alert to the user. These are typically used to trigger background behavior, such as displaying content, personalizing the app interface, or downloading new information from a server. To receive silent push notifications, follow the platform-specific instructions below:
Klaviyo messages can also include key-value pairs (custom data) for both standard and silent push notifications. To receive custom data, follow the platform-specific instructions below:
In-App Forms are messages displayed to mobile app users while they are actively using an app. You can create new In-App Forms in a drag-and-drop editor in the Sign-Up Forms tab in Klaviyo. Follow the instructions in this section to integrate forms with your app. The SDK will display forms according to their targeting and behavior settings and collect delivery and engagement analytics automatically.
In-App Forms supports advanced targeting and segmentation. In your Klaviyo account, you can configure forms to target or exclude specific segments of profiles and configure event-based triggers and delays. See the table below to understand available features by SDK version.
- Import the Klaviyo module
- We strongly recommend using the latest version of the SDK to ensure compatibility with the latest In-App Forms features. The minimum SDK version supporting In-App Forms is 1.2.0, and a feature matrix is provided below. Forms that leverage unsupported features will not appear in your app until you update to a version that supports those features.
- Please read the migration guide if you are upgrading from 1.2.0 to understanding changes to In-App Forms behavior.
| Feature | Minimum SDK Version |
|---|---|
| Basic In-App Forms | 1.2.0+ |
| Time Delay | 2.0.0 |
| Audience Targeting | 2.0.0 |
| Event Triggers | 2.1.0 |
To configure your app to display In-App Forms, call Klaviyo.registerForInAppForms() after initializing the SDK with your public API key. Once registered, the SDK may launch an overlay view at any time to present a form according to its targeting and behavior settings configured in your Klaviyo account.
For the best user experience, we recommend registering after any splash screen or loading animations have completed. Depending on your app's architecture, this might be in a particular Screen's useEffect.
import { Klaviyo } from "klaviyo-react-native-sdk";
...
// call this any time after initializing your public API key
Klaviyo.registerForInAppForms();
A "session" is considered to be a logical unit of user engagement with the app, defined as a series of foreground interactions that occur within a continuous or near-continuous time window. This is an important concept for In-App Forms, as we want to ensure that a user will not see a form multiple times within a single session.
A session will time out after a specified period of inactivity. When a user launches the app, if the time between the previous interaction with the app and the current one exceeds the specified timeout, we will consider this a new session.
This timeout has a default value of 3600 seconds (1 hour), but it can be customized. To do so, pass an FormConfiguration object to the registerForInAppForms() method. For example, to set a session timeout of 30 minutes:
import { Klaviyo } from "klaviyo-react-native-sdk";
let config: FormConfiguration = { sessionTimeoutDuration: 1800 }
Klaviyo.registerForInAppForms(config);
If at any point you need to prevent the SDK from displaying In-App Forms, e.g. when the user logs out, you may call:
import { Klaviyo } from "klaviyo-react-native-sdk";
Klaviyo.unregisterFromInAppForms(config);
Note that after unregistering, the next call to registerForInAppForms() will be considered a new session by the SDK.
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.