@sagepilot-ai/react-native-sdk
v0.3.6
Published
Sagepilot AI React Native chat SDK
Maintainers
Readme
@sagepilot-ai/react-native-sdk
Official React Native SDK for adding Sagepilot chat to iOS and Android apps.
The SDK opens the Sagepilot-hosted chat experience inside a React Native WebView and provides APIs for setup, identity, unread count, attachments, and app-owned launchers.
For full integration docs, see React Native SDK docs.
Requirements
- React 18+
- React Native 0.72+
react-native-webview13+- A Sagepilot workspace ID and chat channel ID
- Secure token storage for production apps
Install
npm install @sagepilot-ai/react-native-sdk@latest react-native-webviewFor secure persisted sessions, install one storage library:
npm install react-native-keychainExpo apps can use expo-secure-store instead:
npx expo install expo-secure-storeThe SDK key is public routing config in the format workspace_id:channel_id. Do not ship server API keys, signing secrets, or private workspace secrets in a React Native app.
Basic Setup
Configure Sagepilot once when your app starts, then mount SagepilotChatProvider near the top of the app.
import * as Keychain from "react-native-keychain";
import { useEffect, type ReactNode } from "react";
import {
SagepilotChat,
SagepilotChatProvider,
createKeychainTokenStorage
} from "@sagepilot-ai/react-native-sdk";
const tokenStorage = createKeychainTokenStorage(Keychain);
export function SagepilotProvider({ children }: { children: ReactNode }) {
useEffect(() => {
let cancelled = false;
async function setupSagepilot() {
await SagepilotChat.configure({
key: "workspace_id:channel_id",
tokenStorage,
presentation: {
style: "sheet",
mobile: true
},
behavior: {
preloadWebView: true,
enableUnreadPolling: true,
waitForIdentifyBeforeComposer: true
}
});
if (!cancelled) {
await SagepilotChat.identify({
userId: "user_123",
email: "[email protected]",
name: "Customer Name"
});
}
}
void setupSagepilot().catch(console.warn);
return () => {
cancelled = true;
SagepilotChat.destroy();
};
}, []);
return <SagepilotChatProvider>{children}</SagepilotChatProvider>;
}export function App() {
return (
<SagepilotProvider>
<RootNavigator />
</SagepilotProvider>
);
}More setup details: Configuration.
Opening Chat
Use the hook for app-owned launchers:
import { Pressable, Text } from "react-native";
import { useSagepilotChat } from "@sagepilot-ai/react-native-sdk";
export function SupportButton() {
const { configured, unreadCount, presentMessages } = useSagepilotChat();
return (
<Pressable disabled={!configured} onPress={presentMessages}>
<Text>
Support{unreadCount > 0 ? ` (${unreadCount})` : ""}
</Text>
</Pressable>
);
}You can also call the public methods directly:
import { SagepilotChat } from "@sagepilot-ai/react-native-sdk";
SagepilotChat.present();
SagepilotChat.presentMessages();
await SagepilotChat.presentMessageComposer("I need help with my order");
await SagepilotChat.presentMessageComposer("I need help with my order", { mode: "auto" });
await SagepilotChat.presentMessageComposer("Start a new request", { mode: "new" });
await SagepilotChat.presentMessageComposer("I need help with this order", { chatId: savedChatId });presentMessageComposer(message) uses { mode: "auto" } by default. It pre-fills the composer and lets Sagepilot reuse an existing conversation when one is available. Use { mode: "new" } only when a workflow should always start a fresh conversation.
presentMessageComposer() returns boolean by default. If behavior.waitForIdentifyBeforeComposer is true and identify() is already in flight, it returns Promise<boolean> and waits up to 60 seconds for identity to finish before opening. You can await it in both cases.
More examples: Opening chat.
Identity
Call identify() after configure() when you know the signed-in customer.
await SagepilotChat.identify({
userId: "user_123",
email: "[email protected]",
name: "Customer Name",
phone: "+15551234567"
});Use waitForIdentifyBeforeComposer: true for authenticated support flows where the composer should wait for an in-flight identity request before opening.
const opened = await SagepilotChat.presentMessageComposer("I need help with my order");When the app user signs out, clear Sagepilot identity/session state:
await SagepilotChat.logout();
// Optional: only call destroy() when your app is tearing down Sagepilot entirely.
SagepilotChat.destroy();logout() clears hosted WebView identity, removes the persisted customer session, and rotates the SDK onto a fresh anonymous session. The next signed-in user can call identify() without reusing the previous user's conversation context.
More details: Identity.
Attachments
The base package supports custom native file-picker adapters. Apps that want Sagepilot's Android in-app CameraX picker can install the optional addon:
npm install @sagepilot-ai/react-native-camera-addon@latestThe base chat SDK does not bundle CameraX. The optional addon adds these Android dependencies through its own Gradle file:
androidx.camera:camera-coreandroidx.camera:camera-camera2androidx.camera:camera-lifecycleandroidx.camera:camera-viewandroidx.exifinterface:exifinterfaceandroidx.activity:activity
By default, the addon uses CameraX 1.5.3, ExifInterface 1.4.2, and AndroidX Activity 1.10.1. Apps can override them from the root Gradle project with sagepilotCameraXVersion, sagepilotExifInterfaceVersion, and sagepilotActivityVersion.
import { SagepilotChat } from "@sagepilot-ai/react-native-sdk";
import { createSagepilotCameraXFilePicker } from "@sagepilot-ai/react-native-camera-addon";
await SagepilotChat.configure({
key: "workspace_id:channel_id",
filePicker: createSagepilotCameraXFilePicker()
});Run a fresh native Android build after installing the addon so React Native autolinking can register the native module.
More details: Native file picker.
Method Return Behavior
| Method | Return behavior |
|---|---|
| SagepilotChat.configure(config) | Promise<SagepilotMobileConfigureResult> |
| SagepilotChat.identify(identity) | Promise<SagepilotIdentifyResult> |
| SagepilotChat.logout() | Promise<SagepilotLogoutResponse> |
| SagepilotChat.getSession() | Promise<SagepilotSessionState> |
| SagepilotChat.getUnreadCount() | Promise<number> |
| SagepilotChat.presentMessageComposer(message?, options?) | boolean or Promise<boolean> when waitForIdentifyBeforeComposer is enabled and identity is pending |
| SagepilotChat.present() | boolean |
| SagepilotChat.presentMessages() | boolean |
| SagepilotChat.dismiss() / hide() / toggle() | boolean |
| SagepilotChat.isPresented() | boolean |
| SagepilotChat.getIdentityState() / getSessionState() / getChannel() | synchronous state |
| SagepilotChat.onIdentify(...) / onConversationCreated(...) / lifecycle subscriptions | unsubscribe function |
| SagepilotChat.destroy() | void |
Full API reference: SDK API reference.
Useful Links
License
MIT
