{"id":29784799,"url":"https://github.com/infoset/infoset-react-native","last_synced_at":"2025-07-27T16:13:21.357Z","repository":{"id":41051788,"uuid":"299137856","full_name":"Infoset/infoset-react-native","owner":"Infoset","description":"Infoset React Native SDK","archived":false,"fork":false,"pushed_at":"2025-05-12T17:13:01.000Z","size":2130,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-24T21:27:25.577Z","etag":null,"topics":["chat","chatbot","expo","infoset","react-native","sdk"],"latest_commit_sha":null,"homepage":"https://infoset.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Infoset.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-27T23:25:16.000Z","updated_at":"2025-05-12T17:13:05.000Z","dependencies_parsed_at":"2022-09-20T01:01:25.275Z","dependency_job_id":null,"html_url":"https://github.com/Infoset/infoset-react-native","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Infoset/infoset-react-native","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Infoset%2Finfoset-react-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Infoset%2Finfoset-react-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Infoset%2Finfoset-react-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Infoset%2Finfoset-react-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Infoset","download_url":"https://codeload.github.com/Infoset/infoset-react-native/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Infoset%2Finfoset-react-native/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267384431,"owners_count":24078578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","chatbot","expo","infoset","react-native","sdk"],"created_at":"2025-07-27T16:13:18.484Z","updated_at":"2025-07-27T16:13:21.348Z","avatar_url":"https://github.com/Infoset.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://badge.fury.io/js/%40infoset%2Freact-native.svg)](https://badge.fury.io/js/%40infoset%2Freact-native)\n![GitHub](https://img.shields.io/github/license/infoset/infoset-react-native)\n![Downloads](https://img.shields.io/npm/dm/%40infoset%2Freact-native.svg)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/13895224/94475996-8de39c80-01d8-11eb-8771-e590b33c612e.png\" alt=\"Infoset\" width=\"250\" /\u003e\n\u003c/p\u003e\n\n# @infoset/react-native\n\nThe 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.\n\n## Features\n\n- Display Infoset live chat within a WebView.\n- Pass visitor information and tags.\n- Customize widget appearance (background color, status bar).\n- Handle new messages, room events, and errors via callbacks.\n- Intercept and handle URL clicks from chat messages.\n- Receive chat transcript data to handle saving/sharing within your app.\n- Compatible with plain React Native CLI projects and Expo (including Expo Go).\n\n## Installation\n\nInstall the library using npm or yarn:\n\n```bash\nnpm install @infoset/react-native\n# or\nyarn add @infoset/react-native\n```\n\n### Peer Dependencies\n\nThis library relies on certain peer dependencies that you need to install and link in your project:\n\n1.  **`react`**: (Your project should already have this)\n2.  **`react-native`**: (Your project should already have this)\n3.  **`react-native-webview`**: Provides the WebView component.\n    ```bash\n    yarn add react-native-webview\n    # or\n    npm install react-native-webview\n    ```\n4.  **`react-native-url-polyfill`**: Provides URL parsing capabilities.\n    ```bash\n    yarn add react-native-url-polyfill\n    # or\n    npm install react-native-url-polyfill\n    ```\n\n### iOS Specific Setup\n\nAfter installing the dependencies, for iOS, navigate to your `ios` directory and run `pod install`:\n\n```bash\ncd ios\npod install\n# or for React Native CLI projects: npx pod-install\n```\n\n### Expo Go Compatibility\n\nGood 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.\n\n## Usage\n\n### 1. Import the ChatWidget\n\n```javascript\nimport { ChatWidget } from '@infoset/react-native';\n// You can also import types if needed:\n// import { ChatWidget, type VisitorType, type ErrorPayload } from '@infoset/react-native';\n```\n\n### 2. Mount the Component\n\nMount the `ChatWidget` component in your app and control its visibility using the `isVisible` prop.\n\n```javascript\nimport React, { useState, useCallback } from 'react';\nimport { View, Button, Linking, SafeAreaView, StyleSheet, Alert } from 'react-native';\nimport { ChatWidget, type VisitorType, type ErrorPayload } from '@infoset/react-native'; // Adjust if your lib name is different\n\n// Replace 'your-library-name' with the actual name of your library package, e.g., '@infoset/react-native'\n\nfunction MyChatScreen() {\n  const [isChatVisible, setIsChatVisible] = useState(false);\n\n  const visitorData: VisitorType = {\n    id: 'user123',\n    firstName: 'John',\n    lastName: 'Doe',\n    email: 'john.doe@example.com',\n  };\n\n  const handleTranscript = useCallback((transcript: string) =\u003e {\n    console.log('Chat Transcript Received (first 100 chars):', transcript.substring(0, 100) + '...');\n    // In a real app, you would implement logic to save or share the transcript\n    // e.g., using expo-file-system, react-native-fs (if not Expo Go), or Share API\n    Alert.alert('Transcript Received!', 'Check console for details.');\n  }, []);\n\n  const handleError = useCallback((error: ErrorPayload) =\u003e {\n    console.error('[App] ChatWidget Error:', `Code: ${error.code}, Message: ${error.message}`, error.data || error.error);\n    // Optionally inform the user, especially for critical errors\n    // Alert.alert(\"Chat Error\", `An error occurred: ${error.message}`);\n  }, []);\n\n  const handleLinkPress = useCallback((url: string) =\u003e {\n    console.log('[App] Link clicked in chat:', url);\n    // Decide how to handle the URL. For example, open all external links in a browser.\n    Linking.canOpenURL(url).then(supported =\u003e {\n      if (supported) {\n        Linking.openURL(url);\n      } else {\n        console.log(\"Don't know how to open URI: \" + url);\n        Alert.alert(\"Cannot Open Link\", \"This link cannot be opened.\");\n      }\n    }).catch(err =\u003e console.error(\"Error opening URL\", err));\n  }, []);\n\n  return (\n    \u003cSafeAreaView style={styles.container}\u003e\n      \u003cView style={styles.buttonContainer}\u003e\n        \u003cButton\n          title={isChatVisible ? \"Hide Chat\" : \"Show Chat\"}\n          onPress={() =\u003e setIsChatVisible(!isChatVisible)}\n        /\u003e\n      \u003c/View\u003e\n\n      \u003cChatWidget\n        isVisible={isChatVisible}\n        apiKey=\"YOUR_API_KEY\"       // Replace with your Infoset API Key\n        iosKey=\"YOUR_IOS_KEY\"       // Replace with your Infoset iOS Key\n        androidKey=\"YOUR_ANDROID_KEY\" // Replace with your Infoset Android Key\n        // webviewUrl=\"YOUR_CUSTOM_CHAT_URL\" // Optional: Defaults to Infoset CDN\n\n        visitor={visitorData}\n        tags={['Support', 'MobileAppUser']}\n\n        color=\"#F5F5F5\" // Optional: background color of the widget area\n        statusBarTheme=\"dark-content\" // Optional: 'auto', 'light-content', or 'dark-content'\n\n        onWidgetHide={() =\u003e {\n          console.log('[App] ChatWidget hidden, setting isVisible to false');\n          setIsChatVisible(false); // Essential to update your state\n        }}\n        onNewMessage={(data) =\u003e console.log('[App] New message:', data.message)}\n        onTranscriptReceived={handleTranscript}\n        onError={handleError}\n        handleUrl={handleLinkPress} // Example of handling URLs\n\n        // Add other lifecycle/event callbacks as needed\n        // onWidgetWillShow={() =\u003e console.log('[App] Chat will show')}\n        // onWidgetShow={() =\u003e console.log('[App] Chat shown')}\n        // onWidgetWillHide={() =\u003e console.log('[App] Chat will hide')}\n        // onRoomOpened={(data) =\u003e console.log('[App] Room opened:', data.roomId)}\n        // onRoomClosed={(data) =\u003e console.log('[App] Room closed:', data.roomId)}\n      /\u003e\n    \u003c/SafeAreaView\u003e\n  );\n}\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n  },\n  buttonContainer: {\n    padding: 10,\n    alignItems: 'center',\n  }\n});\n\nexport default MyChatScreen;\n```\n\n**Important:**\n\n- You must provide your `apiKey`.\n- You should provide either `iosKey` or `androidKey` (or both) depending on the platforms you target. These keys are obtained from your Infoset dashboard.\n- The `onWidgetHide` callback should typically be used to set your local state variable (which controls the `isVisible` prop) to `false`.\n\n### Setting Visitor Information\n\nProvide user details via the `visitor` prop. This helps identify the user on the Infoset dashboard.\n\n```javascript\n\u003cChatWidget\n  // ... other props\n  visitor={{\n    id: 'user-unique-id-456', // Can be string or number\n    email: 'jane.doe@example.com',\n    firstName: 'Jane',\n    lastName: 'Doe',\n    phone: '+15559876543',\n    company: 'Acme Corp',\n    // You can add any custom fields your backend supports\n    customFields: {\n      plan: 'Premium',\n      userId: 12345,\n    },\n  }}\n/\u003e\n```\n\nRefer to the `VisitorType` in your type definitions (e.g., `src/types.ts` or the library's exported types) for all available fields.\n\n### Assigning Chats to Tags\n\nRoute chats to specific agent groups or categories using the `tags` prop.\n\n```javascript\n\u003cChatWidget\n  // ... other props\n  tags={['SalesInquiry', 'VIP_Customer']}\n/\u003e\n```\n\n### Custom URL Handling\n\nBy default, links clicked within the chat messages are opened using `Linking.openURL`. You can override this behavior with the `handleUrl` prop.\n\n```javascript\n\u003cChatWidget\n  // ... other props\n  handleUrl={(url) =\u003e {\n    if (url.includes('myinternalapplink://')) {\n      // Handle internal app navigation\n      console.log('Handling internal link:', url);\n      // myAppNavigation.navigate(url);\n    } else {\n      // Open external links in a browser or InAppBrowser\n      Linking.openURL(url);\n    }\n  }}\n/\u003e\n```\n\n### Receiving Chat Transcript Data\n\nWhen 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).\n\n```javascript\n\u003cChatWidget\n  // ... other props\n  onTranscriptReceived={(transcript) =\u003e {\n    console.log('Transcript data ready for saving/sharing.');\n    // Example: Use Share API (import { Share } from 'react-native';)\n    // Share.share({ message: transcript, title: 'Chat Transcript' });\n    // Example: Save to file using expo-file-system or react-native-fs\n    // (Implementation depends on your project setup)\n  }}\n/\u003e\n```\n\n## API Reference (Props)\n\n| Prop                         | Type                                                                        | Required? | Default                   | Description                                                                                      |\n| :--------------------------- | :-------------------------------------------------------------------------- | :-------- | :------------------------ | :----------------------------------------------------------------------------------------------- |\n| `isVisible`                  | `boolean`                                                                   | **Yes**   | `false`                   | Controls the visibility of the chat widget.                                                      |\n| `apiKey`                     | `string`                                                                    | **Yes**   | -                         | Your Infoset API Key.                                                                            |\n| `iosKey`                     | `string`                                                                    | No        | `undefined`               | Your Infoset iOS Platform Key. Recommended if targeting iOS.                                     |\n| `androidKey`                 | `string`                                                                    | No        | `undefined`               | Your Infoset Android Platform Key. Recommended if targeting Android.                             |\n| `webviewUrl`                 | `string`                                                                    | No        | Infoset CDN URL           | Custom URL for the chat web application.                                                         |\n| `visitor`                    | `VisitorType`                                                               | No        | `undefined`               | An object containing information about the visitor.                                              |\n| `tags`                       | `string[]`                                                                  | No        | `undefined`               | An array of tags to associate with the chat/visitor.                                             |\n| `color`                      | `string`                                                                    | No        | `'#FFFFFF'`               | Background color for the widget's `SafeAreaView`.                                                |\n| `statusBarTheme`             | `'auto' \\| 'light-content' \\| 'dark-content'`                               | No        | `'auto'`                  | Controls the style of the status bar when the widget is visible.                                 |\n| `showLoadingIndicator`       | `boolean`                                                                   | No        | `true`                    | Shows a loading indicator while the WebView content is initializing.                             |\n| `closeButtonBackgroundColor` | `string`                                                                    | No        | `'rgba(0, 0, 0, 0.2)'`    | Background color of the close button visible during initial loading.                             |\n| `closeButtonTextColor`       | `string`                                                                    | No        | Calculated                | Text color of the close button. Calculated based on `color` prop if not provided.                |\n| `onWidgetWillShow`           | `() =\u003e void \\| Promise\u003cvoid\u003e`                                               | No        | `undefined`               | Callback executed just before the widget's show animation begins.                                |\n| `onWidgetShow`               | `() =\u003e void`                                                                | No        | `undefined`               | Callback executed after the widget's show animation is complete.                                 |\n| `onWidgetWillHide`           | `() =\u003e void \\| Promise\u003cvoid\u003e`                                               | No        | `undefined`               | Callback executed just before the widget's hide animation begins.                                |\n| `onWidgetHide`               | `() =\u003e void`                                                                | No        | `undefined`               | Callback executed after the widget is completely hidden. Use this to set `isVisible` to `false`. |\n| `onNewMessage`               | `(payload: { author: Author; message: string; messageId: string }) =\u003e void` | No        | `undefined`               | Callback executed when a new message is received.                                                |\n| `onRoomOpened`               | `(payload: { roomId: number }) =\u003e void`                                     | No        | `undefined`               | Callback executed when a chat room is opened.                                                    |\n| `onRoomClosed`               | `(payload: { roomId: number }) =\u003e void`                                     | No        | `undefined`               | Callback executed when a chat room is closed.                                                    |\n| `onRoomReopened`             | `(payload: { roomId: number }) =\u003e void`                                     | No        | `undefined`               | Callback executed when a chat room is reopened.                                                  |\n| `onError`                    | `(payload: ErrorPayload) =\u003e void`                                           | No        | `undefined`               | Callback executed when an error occurs within the widget or WebView.                             |\n| `handleUrl`                  | `(url: string) =\u003e void`                                                     | No        | Default (Linking.openURL) | Callback to handle URL clicks from within chat messages.                                         |\n| `onTranscriptReceived`       | `(transcript: string) =\u003e void`                                              | No        | `undefined`               | Callback executed with the chat transcript string when requested/available from the web widget.  |\n\n## Example App\n\nThis repository includes an example application to demonstrate the library's usage:\n\n- **`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.\n\nRefer to the `App.tsx` file within the `example/src/` directory for a complete usage example.\n\n## Development Setup (For Team Members)\n\nThis section outlines how to set up the development environment if you are contributing to this library.\n\n1.  **Clone the Repository:**\n    ```bash\n    git clone [https://github.com/Infoset/infoset-react-native.git](https://github.com/Infoset/infoset-react-native.git)\n    cd infoset-react-native\n    ```\n2.  **Install Dependencies:**\n    This project uses Yarn workspaces. Install dependencies from the root directory:\n    ```bash\n    yarn install\n    # If you encounter memory issues, try:\n    # NODE_OPTIONS=\"--max-old-space-size=4096\" yarn install\n    ```\n3.  **Building the Library:**\n    The library source code is in `src/` and needs to be compiled to `lib/`.\n    ```bash\n    yarn build\n    ```\n4.  **Watching for Changes (Recommended for Development):**\n    To automatically rebuild the library when you make changes to the `src/` files:\n    - Open a terminal in the project root and run:\n      ```bash\n      yarn watch:build\n      ```\n    - This will watch for changes and recompile the library.\n5.  **Running the Example App (`example`):**\n\n    - In a **separate terminal window**, also in the project root, you can run the Expo example app:\n      ```bash\n      # To start the Expo development server\n      yarn example start\n      # Then press 'i' to open in iOS simulator or 'a' for Android emulator/device.\n      # Alternatively, to directly launch on a platform:\n      # yarn example ios\n      # yarn example android\n      ```\n    - Changes made in the library's `src/` directory, once recompiled by `yarn watch:build`, should reflect in the running example app (Fast Refresh).\n\n6.  **Code Style \u0026 Linting:**\n    We use ESLint and Prettier for code consistency.\n    ```bash\n    # Check for linting issues\n    yarn lint\n    # Attempt to automatically fix linting issues\n    # yarn lint --fix (Ensure your ESLint config supports this effectively)\n    # Format code with Prettier\n    npx prettier --write \"**/*.{js,ts,tsx,json,md}\"\n    ```\n7.  **Running Tests:**\n    ```bash\n    yarn test\n    ```\n\n## Versioning and Releasing (For Maintainers)\n\nThis project uses [`release-it`](https://github.com/release-it/release-it) with [`@release-it/conventional-changelog`](https://github.com/release-it/conventional-changelog) to automate versioning, changelog generation, Git tagging, npm publishing, and GitHub releases. Commits should follow the [Conventional Commits](https://www.ventionalcommits.org/) specification.\n\n### Prerequisites\n\n- Ensure you have publish access to the `@infoset/react-native` package on npm.\n- Ensure all changes are merged into the `master` branch and the branch is clean.\n- Ensure all tests are passing.\n\n### Creating a Beta Release\n\nTo create a pre-release (e.g., `1.8.0-beta.0`):\n\n1.  Make sure your local `master` branch is up-to-date with the remote.\n2.  Run the `release-it` command with `--preRelease=beta` and specify the npm dist-tag:\n\n    ```bash\n    npx release-it \u003cversion_or_increment\u003e --preRelease=beta --npm.tag=beta\n    ```\n\n    - Replace `\u003cversion_or_increment\u003e` with the desired version (e.g., `1.8.0`) or an increment keyword like `minor`, `patch`. `release-it` will append the beta part (e.g., `1.8.0-beta.0`).\n    - Example for a specific version: `npx release-it 1.8.0 --preRelease=beta --npm.tag=beta`\n    - Example for a minor pre-release: `npx release-it minor --preRelease=beta --npm.tag=beta`\n    - You can add `--ci` to automate prompts or run it interactively.\n\n    This command will:\n\n    - Bump the version in `package.json` (e.g., to `1.8.0-beta.0`).\n    - Generate/update the changelog.\n    - Commit these changes.\n    - Create a Git tag (e.g., `v1.8.0-beta.0`).\n    - Push commits and tags to the remote.\n    - Publish the package to npm with the `beta` dist-tag. This prevents it from becoming the `latest` tag.\n    - Create a GitHub Release.\n\nUsers can then install this beta version using `npm install @infoset/react-native@beta` or `npm install @infoset/react-native@1.8.0-beta.0`.\n\n### Creating a Stable Release\n\nTo create a stable release (e.g., `1.8.0`):\n\n1.  Ensure all beta testing is complete and the `master` branch is ready for release.\n2.  Run the `release-it` command:\n\n    ```bash\n    npx release-it \u003cversion_or_increment\u003e\n    ```\n\n    - Example for a specific version: `npx release-it 1.8.0`\n    - Example for a patch release: `npx release-it patch`\n\n    This command will:\n\n    - Bump the version in `package.json`.\n    - Generate/update the changelog.\n    - Commit these changes.\n    - Create a Git tag (e.g., `v1.8.0`).\n    - Push commits and tags to the remote.\n    - Publish the package to npm (it will become the `latest` version).\n    - Create a GitHub Release.\n\nAlways review the changes proposed by `release-it` before confirming.\n\n## Contributing\n\nContributions 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.\n\n## License\n\nMIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfoset%2Finfoset-react-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfoset%2Finfoset-react-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfoset%2Finfoset-react-native/lists"}