The official Infoset React Native SDK allows you to seamlessly integrate the Infoset Live Chat widget into your React Native applications. Engage with your users directly within your mobile app.
- Display Infoset live chat within a WebView.
- Pass visitor information and tags.
- Customize widget appearance (background color, status bar).
- Handle new messages, room events, and errors via callbacks.
- Intercept and handle URL clicks from chat messages.
- Receive chat transcript data to handle saving/sharing within your app.
- Compatible with plain React Native CLI projects and Expo (including Expo Go).
Install the library using npm or yarn:
npm install @infoset/react-native
# or
yarn add @infoset/react-native
This library relies on certain peer dependencies that you need to install and link in your project:
react
: (Your project should already have this)react-native
: (Your project should already have this)react-native-webview
: Provides the WebView component.yarn add react-native-webview # or npm install react-native-webview
react-native-url-polyfill
: Provides URL parsing capabilities.yarn add react-native-url-polyfill # or npm install react-native-url-polyfill
After installing the dependencies, for iOS, navigate to your ios
directory and run pod install
:
cd ios
pod install
# or for React Native CLI projects: npx pod-install
Good news! This library is compatible with Expo Go. Since it only relies on react-native-webview
(which is included in Expo Go) and react-native-url-polyfill
(a JavaScript-only polyfill), you can use it in projects running on Expo Go without needing a development build for basic functionality.
import { ChatWidget } from '@infoset/react-native';
// You can also import types if needed:
// import { ChatWidget, type VisitorType, type ErrorPayload } from '@infoset/react-native';
Mount the ChatWidget
component in your app and control its visibility using the isVisible
prop.
import React, { useState, useCallback } from 'react';
import { View, Button, Linking, SafeAreaView, StyleSheet, Alert } from 'react-native';
import { ChatWidget, type VisitorType, type ErrorPayload } from '@infoset/react-native'; // Adjust if your lib name is different
// Replace 'your-library-name' with the actual name of your library package, e.g., '@infoset/react-native'
function MyChatScreen() {
const [isChatVisible, setIsChatVisible] = useState(false);
const visitorData: VisitorType = {
id: 'user123',
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
};
const handleTranscript = useCallback((transcript: string) => {
console.log('Chat Transcript Received (first 100 chars):', transcript.substring(0, 100) + '...');
// In a real app, you would implement logic to save or share the transcript
// e.g., using expo-file-system, react-native-fs (if not Expo Go), or Share API
Alert.alert('Transcript Received!', 'Check console for details.');
}, []);
const handleError = useCallback((error: ErrorPayload) => {
console.error('[App] ChatWidget Error:', `Code: ${error.code}, Message: ${error.message}`, error.data || error.error);
// Optionally inform the user, especially for critical errors
// Alert.alert("Chat Error", `An error occurred: ${error.message}`);
}, []);
const handleLinkPress = useCallback((url: string) => {
console.log('[App] Link clicked in chat:', url);
// Decide how to handle the URL. For example, open all external links in a browser.
Linking.canOpenURL(url).then(supported => {
if (supported) {
Linking.openURL(url);
} else {
console.log("Don't know how to open URI: " + url);
Alert.alert("Cannot Open Link", "This link cannot be opened.");
}
}).catch(err => console.error("Error opening URL", err));
}, []);
return (
<SafeAreaView style={styles.container}>
<View style={styles.buttonContainer}>
<Button
title={isChatVisible ? "Hide Chat" : "Show Chat"}
onPress={() => setIsChatVisible(!isChatVisible)}
/>
</View>
<ChatWidget
isVisible={isChatVisible}
apiKey="YOUR_API_KEY" // Replace with your Infoset API Key
iosKey="YOUR_IOS_KEY" // Replace with your Infoset iOS Key
androidKey="YOUR_ANDROID_KEY" // Replace with your Infoset Android Key
// webviewUrl="YOUR_CUSTOM_CHAT_URL" // Optional: Defaults to Infoset CDN
visitor={visitorData}
tags={['Support', 'MobileAppUser']}
color="#F5F5F5" // Optional: background color of the widget area
statusBarTheme="dark-content" // Optional: 'auto', 'light-content', or 'dark-content'
onWidgetHide={() => {
console.log('[App] ChatWidget hidden, setting isVisible to false');
setIsChatVisible(false); // Essential to update your state
}}
onNewMessage={(data) => console.log('[App] New message:', data.message)}
onTranscriptReceived={handleTranscript}
onError={handleError}
handleUrl={handleLinkPress} // Example of handling URLs
// Add other lifecycle/event callbacks as needed
// onWidgetWillShow={() => console.log('[App] Chat will show')}
// onWidgetShow={() => console.log('[App] Chat shown')}
// onWidgetWillHide={() => console.log('[App] Chat will hide')}
// onRoomOpened={(data) => console.log('[App] Room opened:', data.roomId)}
// onRoomClosed={(data) => console.log('[App] Room closed:', data.roomId)}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
buttonContainer: {
padding: 10,
alignItems: 'center',
}
});
export default MyChatScreen;
Important:
- You must provide your
apiKey
. - You should provide either
iosKey
orandroidKey
(or both) depending on the platforms you target. These keys are obtained from your Infoset dashboard. - The
onWidgetHide
callback should typically be used to set your local state variable (which controls theisVisible
prop) tofalse
.
Provide user details via the visitor
prop. This helps identify the user on the Infoset dashboard.
<ChatWidget
// ... other props
visitor={{
id: 'user-unique-id-456', // Can be string or number
email: 'jane.doe@example.com',
firstName: 'Jane',
lastName: 'Doe',
phone: '+15559876543',
company: 'Acme Corp',
// You can add any custom fields your backend supports
customFields: {
plan: 'Premium',
userId: 12345,
},
}}
/>
Refer to the VisitorType
in your type definitions (e.g., src/types.ts
or the library's exported types) for all available fields.
Route chats to specific agent groups or categories using the tags
prop.
<ChatWidget
// ... other props
tags={['SalesInquiry', 'VIP_Customer']}
/>
By default, links clicked within the chat messages are opened using Linking.openURL
. You can override this behavior with the handleUrl
prop.
<ChatWidget
// ... other props
handleUrl={(url) => {
if (url.includes('myinternalapplink://')) {
// Handle internal app navigation
console.log('Handling internal link:', url);
// myAppNavigation.navigate(url);
} else {
// Open external links in a browser or InAppBrowser
Linking.openURL(url);
}
}}
/>
When the chat transcript is available (e.g., user requests a download from within the web widget), the onTranscriptReceived
callback is triggered with the transcript content as a string. Your application is responsible for handling this string (e.g., saving it to a file, sharing it).
<ChatWidget
// ... other props
onTranscriptReceived={(transcript) => {
console.log('Transcript data ready for saving/sharing.');
// Example: Use Share API (import { Share } from 'react-native';)
// Share.share({ message: transcript, title: 'Chat Transcript' });
// Example: Save to file using expo-file-system or react-native-fs
// (Implementation depends on your project setup)
}}
/>
Prop | Type | Required? | Default | Description |
---|---|---|---|---|
isVisible |
boolean |
Yes | false |
Controls the visibility of the chat widget. |
apiKey |
string |
Yes | - | Your Infoset API Key. |
iosKey |
string |
No | undefined |
Your Infoset iOS Platform Key. Recommended if targeting iOS. |
androidKey |
string |
No | undefined |
Your Infoset Android Platform Key. Recommended if targeting Android. |
webviewUrl |
string |
No | Infoset CDN URL | Custom URL for the chat web application. |
visitor |
VisitorType |
No | undefined |
An object containing information about the visitor. |
tags |
string[] |
No | undefined |
An array of tags to associate with the chat/visitor. |
color |
string |
No | '#FFFFFF' |
Background color for the widget's SafeAreaView . |
statusBarTheme |
'auto' | 'light-content' | 'dark-content' |
No | 'auto' |
Controls the style of the status bar when the widget is visible. |
showLoadingIndicator |
boolean |
No | true |
Shows a loading indicator while the WebView content is initializing. |
closeButtonBackgroundColor |
string |
No | 'rgba(0, 0, 0, 0.2)' |
Background color of the close button visible during initial loading. |
closeButtonTextColor |
string |
No | Calculated | Text color of the close button. Calculated based on color prop if not provided. |
onWidgetWillShow |
() => void | Promise<void> |
No | undefined |
Callback executed just before the widget's show animation begins. |
onWidgetShow |
() => void |
No | undefined |
Callback executed after the widget's show animation is complete. |
onWidgetWillHide |
() => void | Promise<void> |
No | undefined |
Callback executed just before the widget's hide animation begins. |
onWidgetHide |
() => void |
No | undefined |
Callback executed after the widget is completely hidden. Use this to set isVisible to false . |
onNewMessage |
(payload: { author: Author; message: string; messageId: string }) => void |
No | undefined |
Callback executed when a new message is received. |
onRoomOpened |
(payload: { roomId: number }) => void |
No | undefined |
Callback executed when a chat room is opened. |
onRoomClosed |
(payload: { roomId: number }) => void |
No | undefined |
Callback executed when a chat room is closed. |
onRoomReopened |
(payload: { roomId: number }) => void |
No | undefined |
Callback executed when a chat room is reopened. |
onError |
(payload: ErrorPayload) => void |
No | undefined |
Callback executed when an error occurs within the widget or WebView. |
handleUrl |
(url: string) => void |
No | Default (Linking.openURL) | Callback to handle URL clicks from within chat messages. |
onTranscriptReceived |
(transcript: string) => void |
No | undefined |
Callback executed with the chat transcript string when requested/available from the web widget. |
This repository includes an example application to demonstrate the library's usage:
example/
: An example app set up with Expo, demonstrating usage in an Expo environment. It should work with Expo Go for this library's core functionality. If you add other native modules to the example, you might need a development client.
Refer to the App.tsx
file within the example/src/
directory for a complete usage example.
This section outlines how to set up the development environment if you are contributing to this library.
-
Clone the Repository:
git clone [https://github.com/Infoset/infoset-react-native.git](https://github.com/Infoset/infoset-react-native.git) cd infoset-react-native
-
Install Dependencies: This project uses Yarn workspaces. Install dependencies from the root directory:
yarn install # If you encounter memory issues, try: # NODE_OPTIONS="--max-old-space-size=4096" yarn install
-
Building the Library: The library source code is in
src/
and needs to be compiled tolib/
.yarn build
-
Watching for Changes (Recommended for Development): To automatically rebuild the library when you make changes to the
src/
files:- Open a terminal in the project root and run:
yarn watch:build
- This will watch for changes and recompile the library.
- Open a terminal in the project root and run:
-
Running the Example App (
example
):- In a separate terminal window, also in the project root, you can run the Expo example app:
# To start the Expo development server yarn example start # Then press 'i' to open in iOS simulator or 'a' for Android emulator/device. # Alternatively, to directly launch on a platform: # yarn example ios # yarn example android
- Changes made in the library's
src/
directory, once recompiled byyarn watch:build
, should reflect in the running example app (Fast Refresh).
- In a separate terminal window, also in the project root, you can run the Expo example app:
-
Code Style & Linting: We use ESLint and Prettier for code consistency.
# Check for linting issues yarn lint # Attempt to automatically fix linting issues # yarn lint --fix (Ensure your ESLint config supports this effectively) # Format code with Prettier npx prettier --write "**/*.{js,ts,tsx,json,md}"
-
Running Tests:
yarn test
This project uses release-it
with @release-it/conventional-changelog
to automate versioning, changelog generation, Git tagging, npm publishing, and GitHub releases. Commits should follow the Conventional Commits specification.
- Ensure you have publish access to the
@infoset/react-native
package on npm. - Ensure all changes are merged into the
master
branch and the branch is clean. - Ensure all tests are passing.
To create a pre-release (e.g., 1.8.0-beta.0
):
-
Make sure your local
master
branch is up-to-date with the remote. -
Run the
release-it
command with--preRelease=beta
and specify the npm dist-tag:npx release-it <version_or_increment> --preRelease=beta --npm.tag=beta
- Replace
<version_or_increment>
with the desired version (e.g.,1.8.0
) or an increment keyword likeminor
,patch
.release-it
will append the beta part (e.g.,1.8.0-beta.0
). - Example for a specific version:
npx release-it 1.8.0 --preRelease=beta --npm.tag=beta
- Example for a minor pre-release:
npx release-it minor --preRelease=beta --npm.tag=beta
- You can add
--ci
to automate prompts or run it interactively.
This command will:
- Bump the version in
package.json
(e.g., to1.8.0-beta.0
). - Generate/update the changelog.
- Commit these changes.
- Create a Git tag (e.g.,
v1.8.0-beta.0
). - Push commits and tags to the remote.
- Publish the package to npm with the
beta
dist-tag. This prevents it from becoming thelatest
tag. - Create a GitHub Release.
- Replace
Users can then install this beta version using npm install @infoset/react-native@beta
or npm install @infoset/react-native@1.8.0-beta.0
.
To create a stable release (e.g., 1.8.0
):
-
Ensure all beta testing is complete and the
master
branch is ready for release. -
Run the
release-it
command:npx release-it <version_or_increment>
- Example for a specific version:
npx release-it 1.8.0
- Example for a patch release:
npx release-it patch
This command will:
- Bump the version in
package.json
. - Generate/update the changelog.
- Commit these changes.
- Create a Git tag (e.g.,
v1.8.0
). - Push commits and tags to the remote.
- Publish the package to npm (it will become the
latest
version). - Create a GitHub Release.
- Example for a specific version:
Always review the changes proposed by release-it
before confirming.
Contributions are welcome! Please feel free to submit a pull request or open an issue on the GitHub repository. Refer to CONTRIBUTING.md
for more detailed guidelines.
MIT License.