How to get started
Installation
Add dependency via npm or yarn package managers:
- npm
- yarn
npm install @inappstory/react-native-sdk
yarn add @inappstory/react-native-sdk
Requirements
The React Native SDK supports both the New Architecture (Fabric, Turbo Modules, Codegen) and the Old Architecture (Bridge, Paper).
- React Native:
0.68+(up to0.86.0) - iOS:
13.0+(bundlesiOS SDK 1.29.5) - Android:
API 24+(bundlesAndroid SDK 1.25.4)
iOS
Install CocoaPods dependencies:
cd ios && pod install
Note on
use_frameworks!: The SDK works out of the box with standard CocoaPods setups. If your project explicitly requires static frameworks (use_frameworks! :linkage => :staticorUSE_FRAMEWORKS=static), that is also supported.
Android
Step 1:
Make sure to update your Android SDK versions in android/app/build.gradle:
minSdkVersion = 24
compileSdkVersion = 35
targetSdkVersion = 35
If you use the New Architecture (default in React Native 0.76+), ensure newArchEnabled = true in your gradle.properties.
Step 2:
Update MainApplication class:
package com.example.yourapp
import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost
import com.inappstory.reactnativesdk.InAppStory
class MainApplication : Application(), ReactApplication {
override val reactHost: ReactHost by lazy {
getDefaultReactHost(
context = applicationContext,
packageList =
PackageList(this).packages.apply {
// Packages that cannot be autolinked yet can be added manually here, for example:
// add(MyReactNativePackage())
},
)
}
override fun onCreate() {
super.onCreate()
InAppStory.initSDK(this)
loadReactNative(this)
}
}
Step 3:
Update MainActivity class:
package com.example.yourapp;
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import com.inappstory.reactnativesdk.activity.InAppStoryActivity
class MainActivity : ReactActivity() {
class MainActivity : InAppStoryActivity() {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
override fun getMainComponentName(): String = "your_app"
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
*/
override fun createReactActivityDelegate(): ReactActivityDelegate =
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
}
Why do I need this?
InAppStoryActivity extends ReactActivity and intercepts the Back button tap at the Android hardware/software
level. This feature is only used when an In-App message (IAM) is shown. It first redirects
the tap through the SDK, so pressing the Back button closes the In-App message within the app rather than
navigating
to another screen. If MainActivity continues to extend ReactActivity, the Back button bypasses the SDK, and
the
reader will not close correctly.
Basic Initialization
Initialize the SDK by creating StoryManager and configuring AppearanceManager:
import { StoryManager, AppearanceManager } from '@inappstory/react-native-sdk';
export const storyManager = await StoryManager.create({
apiKey: '<your-api-key>',
userId: '<user-id>',
});
export const appearanceManager = new AppearanceManager();
Complete setup example (StoryService.ts)
import {
StoryManager,
AppearanceManager,
type StoryManagerConfig,
StoriesListCardTitlePosition,
StoriesListCardViewVariant,
StoriesListCardTitleTextAlign,
StoryReaderCloseButtonPosition,
StoryReaderSwipeStyle,
} from '@inappstory/react-native-sdk';
import { Linking, Platform } from 'react-native';
const config: StoryManagerConfig = {
apiKey: '<your-api-key>',
userId: '<user-id>',
tags: ['tag1', 'tag2'],
placeholders: { username: 'Guest' },
lang: 'en-US',
defaultMuted: true,
};
export const storyManager = await StoryManager.create(config);
// Handle CTA clicks (buttons / deeplinks)
storyManager.storyLinkClickHandler = (payload) => {
if (payload.data.url) {
Linking.openURL(payload.data.url);
}
};
export const appearanceManager = new AppearanceManager()
.setCommonOptions({
hasLike: true,
hasLikeButton: true,
hasDislikeButton: false,
hasFavorite: true,
hasShare: true,
})
.setStoriesListOptions({
card: {
title: {
fontSize: 12,
fontWeight: 600,
fontFamily: Platform.OS === 'ios' ? 'System' : 'Roboto',
lineHeight: 14,
lineClamp: 2,
textAlign: StoriesListCardTitleTextAlign.LEFT,
position: StoriesListCardTitlePosition.CARD_INSIDE_BOTTOM,
},
height: 150,
variant: StoriesListCardViewVariant.RECTANGLE,
},
sidePadding: 16,
})
.setStoryReaderOptions({
closeButtonPosition: StoryReaderCloseButtonPosition.RIGHT,
scrollStyle: StoryReaderSwipeStyle.FLAT,
slideBorderRadius: 8,
});
Optional Settings
AppVersion override
Override app version and build for targeting (useful for CodePush):
const storyManager = await StoryManager.create({
apiKey: '<your-api-key>',
appVersion: {
version: '3.0.0',
build: 123,
},
});
Cache size and anonymous mode
const storyManager = await StoryManager.create({
apiKey: '<your-api-key>',
// Native story cache size. Android-only (iOS manages its own cache)
cacheSize: 'medium', // 'small' | 'medium' | 'large'
// Anonymous mode: no userId is sent to the backend
anonymous: true,
});
Next steps
- Render stories in your UI with Stories List
- Configure styling with Appearance
- Learn how to migrate from older versions in Migrations