@rematter/pylon-react-native
v0.1.7
Published
Pylon Chat SDK for React Native
Downloads
572
Readme
Pylon Chat SDK for React Native
Add Pylon's chat widget to your React Native application to enable in-app customer support.
Requirements
- React Native >= 0.70.0
- iOS >= 13.0
- Android minSdkVersion >= 24
Note: This package uses native modules. For Expo projects, you'll need a development build.
Installation
This SDK is distributed as source code and installed from a local directory.
Step 1: Clone the Repository
Clone the SDK repository anywhere on your machine, but preferably forked into your own repository:
git clone https://github.com/pylon-labs/sdk-mobile.gitStep 2: Install the Package
From your React Native project root, install from the local path:
npm install /path/to/sdk-mobile/react-native
# or
yarn add file:/path/to/sdk-mobile/react-nativeWhat happens automatically:
- npm runs the
preparescript (compiles TypeScript, copies native code) - Package is installed to
node_modules/@pylon/react-native-chat/
Step 3: Link Native Code
The SDK includes native Swift (iOS) and Kotlin (Android) code that needs to be linked to your app.
For Expo projects:
Expo apps don't have native folders by default. Generate them:
npx expo install expo-dev-client
npx expo prebuildThis creates ios/ and android/ folders with the SDK's native code linked.
For bare React Native projects:
iOS requires CocoaPods linking:
cd ios && pod install && cd ..Android auto-links automatically (no action needed).
Step 4: Get Your Pylon App ID
- Login to app.usepylon.com
- Go to Settings → Chat Widget
- Copy your App ID
Quick Start
import { PylonChatView, type PylonChatViewRef } from "@pylon/react-native-chat";
import { useRef } from "react";
import { StyleSheet, View } from "react-native";
export default function App() {
const pylonRef = useRef<PylonChatViewRef>(null);
const config = {
appId: "YOUR_APP_ID", // Get from app.usepylon.com/settings/chat-widget
widgetBaseUrl: "https://widget.usepylon.com",
};
const user = {
email: "[email protected]",
name: "User Name",
};
return (
<View style={styles.container}>
{/* Your app content */}
<Text>My App Content</Text>
{/* Pylon Chat Widget - renders as overlay */}
<PylonChatView
ref={pylonRef}
config={config}
user={user}
style={styles.chat}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
chat: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
},
});Identity Verification (Strongly Recommended):
We strongly recommend setting up Identity Verification. The emailHash needs to be generated by the server responsible for authorizing your mobile app.
const user = {
email: "[email protected]",
name: "User Name",
emailHash: "sha256_hash_generated_by_server", // Add this for identity verification
};API Reference
PylonChatView Props
config (required)
{
appId: string; // Your Pylon app ID (required)
widgetBaseUrl?: string; // Default: "https://widget.usepylon.com"
enableLogging?: boolean; // Enable debug logs (default: false)
debugMode?: boolean; // Show debug overlay (default: false)
}user (required)
{
email: string; // User's email (required)
name: string; // User's name (required)
avatarUrl?: string; // User's avatar URL
emailHash?: string; // SHA-256 hash for identity verification
accountId?: string; // Your internal account ID
accountExternalId?: string; // External system account ID
}listener (optional)
Event callbacks for chat interactions:
{
onPylonLoaded?: () => void;
onPylonInitialized?: () => void;
onPylonReady?: () => void;
onChatOpened?: () => void;
onChatClosed?: (wasOpen: boolean) => void;
onUnreadCountChanged?: (count: number) => void;
onMessageReceived?: (message: string) => void;
onPylonError?: (error: string) => void;
}style (optional)
Standard React Native ViewStyle. Typically used to position the widget:
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
}}Imperative Methods (via ref)
const pylonRef = useRef<PylonChatViewRef>(null);
// Control chat window
pylonRef.current?.openChat();
pylonRef.current?.closeChat();
// Control chat bubble
pylonRef.current?.showChatBubble();
pylonRef.current?.hideChatBubble();
// Send messages programmatically
pylonRef.current?.showNewMessage("Hello from the app!", false);
pylonRef.current?.showNewMessage("<p><strong>HTML</strong> message</p>", true);
// Set custom fields for new issues
pylonRef.current?.setNewIssueCustomFields({
source: "mobile-app",
version: "1.2.3",
platform: Platform.OS,
});
// Show specific forms
pylonRef.current?.showTicketForm("form-id");
pylonRef.current?.showKnowledgeBaseArticle("article-id");
// Pre-fill ticket form fields
pylonRef.current?.setTicketFormFields({
subject: "Issue from mobile app",
description: "User reported...",
});
// Identity verification
pylonRef.current?.updateEmailHash("sha256_hash");Usage Patterns
Basic Setup with Event Listeners
export default function App() {
const pylonRef = useRef<PylonChatViewRef>(null);
const [unreadCount, setUnreadCount] = useState(0);
const config = {
appId: "YOUR_APP_ID",
};
const user = {
email: "[email protected]",
name: "User Name",
};
const listener = {
onChatOpened: () => console.log("Chat opened"),
onChatClosed: (wasOpen) => console.log("Chat closed", wasOpen),
onUnreadCountChanged: (count) => setUnreadCount(count),
onMessageReceived: (msg) => console.log("New message:", msg),
onPylonError: (error) => console.error("Pylon error:", error),
};
return (
<View style={{ flex: 1 }}>
<MyAppContent />
{unreadCount > 0 && <Badge count={unreadCount} />}
<PylonChatView
ref={pylonRef}
config={config}
user={user}
listener={listener}
style={StyleSheet.absoluteFill}
/>
</View>
);
}With Safe Area Insets
import { useSafeAreaInsets } from "react-native-safe-area-context";
export default function App() {
const insets = useSafeAreaInsets();
return (
<View style={{ flex: 1 }}>
<MyAppContent />
<PylonChatView
config={config}
user={user}
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
paddingTop: insets.top,
paddingBottom: insets.bottom,
}}
/>
</View>
);
}Conditional Rendering (User Login)
export default function App() {
const [currentUser, setCurrentUser] = useState(null);
return (
<View style={{ flex: 1 }}>
<MyAppContent />
{currentUser && (
<PylonChatView
config={{ appId: "YOUR_APP_ID" }}
user={{
email: currentUser.email,
name: currentUser.name,
}}
style={StyleSheet.absoluteFill}
/>
)}
</View>
);
}Custom Fields and Metadata
export default function App() {
const pylonRef = useRef<PylonChatViewRef>(null);
useEffect(() => {
// Set custom fields when component mounts
pylonRef.current?.setNewIssueCustomFields({
app_version: "1.2.3",
platform: Platform.OS,
device_model: DeviceInfo.getModel(),
user_tier: "premium",
});
}, []);
return (
<View style={{ flex: 1 }}>
<MyAppContent />
<PylonChatView
ref={pylonRef}
config={config}
user={user}
style={StyleSheet.absoluteFill}
/>
</View>
);
}Known Limitations
Android: Clickable Elements in Chat Widget
Issue: On Android React Native specifically, clickable elements associated with an unopened chat widget (such as surveys) besides the chat bubble do not currently work. The chat bubble itself functions correctly for opening and closing the widget.
Workaround: This is a known platform limitation related to touch event handling between React Native and Android.
Need this functionality? Please contact the Pylon team if your application requires interactive elements like surveys in the Android React Native chat widget. We'd love to hear about your use case and prioritize a smarter React Native Android touch handler.
Troubleshooting
Android: Java Version Issues
Error: Unsupported class file major version 69
Solution: Install Java 17:
brew install openjdk@17
export JAVA_HOME=$(/usr/libexec/java_home -v 17)iOS: CocoaPods Encoding Issues
Error: Unicode Normalization not appropriate for ASCII-8BIT
Solution:
export LANG=en_US.UTF-8
cd ios && pod installExpo: Development Build Required
Error: No development build installed
Solution: This package uses native modules and cannot run in Expo Go:
npx expo install expo-dev-client
npx expo prebuild
npx expo run:ios # or expo run:androidModule Not Found
Error: Invariant Violation: View config not found for component RNPylonChatView
Solution: Clean and rebuild:
# Expo
rm -rf ios android .expo
npx expo prebuild --clean
npx expo run:ios
# Bare React Native
cd ios && pod install && cd ..
npx react-native run-iosTouch Events Not Working
If touches aren't passing through to views behind the chat bubble:
- Use
position: "absolute"and cover the full screen - Don't wrap
PylonChatViewin additional Views that intercept touches - The native SDK handles touch pass-through automatically
// ✅ Correct
<View style={{ flex: 1 }}>
<ScrollView>{/* Your content */}</ScrollView>
<PylonChatView style={StyleSheet.absoluteFill} {...props} />
</View>
// ❌ Wrong - extra wrapper intercepts touches
<View style={{ flex: 1 }}>
<ScrollView>{/* Your content */}</ScrollView>
<View style={StyleSheet.absoluteFill}>
<PylonChatView style={{ flex: 1 }} {...props} />
</View>
</View>Architecture
This package wraps the native iOS and Android Pylon Chat SDKs using React Native's native module system:
┌─────────────────────────────────────────────────────────────┐
│ React Native (JavaScript/TypeScript) │
│ <PylonChatView /> │
└───────────────────────┬─────────────────────────────────────┘
│ Native Bridge
┌───────────────────────▼─────────────────────────────────────┐
│ Native Module (iOS: Swift, Android: Kotlin) │
│ - RNPylonChatView.swift / RNPylonChatView.kt │
│ - Props → Native config conversion │
│ - Event forwarding to JS │
└───────────────────────┬─────────────────────────────────────┘
│
┌───────────────────────▼─────────────────────────────────────┐
│ Native SDK (PylonChat) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ WebView (Pylon Chat Widget) │ │
│ │ - Loads from widget.usepylon.com │ │
│ │ - JavaScript ↔ Native bridge │ │
│ │ - Touch pass-through when collapsed │ │
│ │ - Real-time messaging │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘The widget is WebView-based, providing consistent functionality with the web SDK while native code handles platform-specific integration.
Demo App
See demo-app/README.md for a complete example application demonstrating all SDK features.
Support
For issues or questions, please reach out to the Pylon team.
