An open API service indexing awesome lists of open source software.

https://github.com/crisp-im/crisp-sdk-react-native

:package: Include the Crisp chat widget in your React Native app
https://github.com/crisp-im/crisp-sdk-react-native

chatbox crisp react-native sdk

Last synced: 4 months ago
JSON representation

:package: Include the Crisp chat widget in your React Native app

Awesome Lists containing this project

README

          



crisp-banner



crisp-sdk-react-native


The official Crisp SDK for React Native — Add live chat to your Expo & React Native apps



npm version


license

Expo SDK 51+
platforms


See Crisp Support Chat SDKs  • 
React Native Support Chat SDK  • 
Developer Docs

---

Trusted by


Fruitz
Fruitz
 · 
and many more companies rely on Crisp to power their in-app customer support.

---


Demo



---

> [!WARNING]
> **Minimum Expo SDK version**
>
> | SDK Version | Expo Compatibility |
> |---|---|
> | **0.2.0+** | Expo SDK 54+ (AGP 8.9.1+ required by Crisp Android SDK 2.0.16+) |
> | **0.1.4** | Expo SDK 51+ |
>
> If you are on Expo 53 or older, pin to version 0.1.4:
> ```bash
> npx expo install crisp-sdk-react-native@0.1.4
> ```

> [!WARNING]
> **Expo Go is Not Supported**
>
> The Crisp SDK uses native modules that are not available in Expo Go. You must use a [development build](https://docs.expo.dev/develop/development-builds/introduction/):
>
> ```bash
> npx expo run:ios
> # or
> npx expo run:android
> ```

---

## Installation

### For Expo Apps

Install the SDK using your preferred package manager:

```bash
# Using bun
bunx expo install crisp-sdk-react-native

# Using pnpm
pnpm dlx expo install crisp-sdk-react-native

# Using npm
npx expo install crisp-sdk-react-native

# Using yarn
yarn dlx expo install crisp-sdk-react-native
```

### For Bare React Native Apps

This guide is for React Native developers who want to integrate Crisp using the Expo SDK in a project that doesn't use Expo as its development framework.

#### Prerequisites

Before starting, ensure you have:

- React Native 0.74+
- iOS deployment target 15.1+
- Android minSdkVersion 24+
- Node.js 18+

#### Step 1: Install Expo Modules

Run the following command in your project root:

```bash
npx install-expo-modules@latest
```

This command automatically configures your iOS and Android projects to support Expo modules.

> [!NOTE]
> For comprehensive installation details or manual installation steps, refer to [Expo's official guide](https://docs.expo.dev/bare/installing-expo-modules/).

#### Step 2: Install Crisp SDK

```bash
# Using npm
npm install crisp-sdk-react-native

# Using yarn
yarn add crisp-sdk-react-native

# Using pnpm
pnpm add crisp-sdk-react-native

# Using bun
bun add crisp-sdk-react-native
```

#### Step 3: Platform Configuration

**iOS:**

```bash
cd ios && pod install
```

**Android:**

Ensure your `android/app/build.gradle` has:

```gradle
android {
compileSdkVersion 36

defaultConfig {
minSdkVersion 24
targetSdkVersion 36
}
}
```

---

## Configuration

### Get Your Website ID

To use the Crisp SDK, you need your Website ID from the Crisp Dashboard.

1. [Sign up for a free account](https://app.crisp.chat/initiate/signup/) on Crisp (or log in)
2. Go to **Settings** > **Website Settings** > **Setup instructions**
3. Copy your Website ID


Setup and Integrations

### Initialize Crisp

Configure the SDK at app startup with your Website ID:

```typescript
import { useEffect } from "react";
import { configure } from "crisp-sdk-react-native";

export default function App() {
useEffect(() => {
configure("YOUR_WEBSITE_ID");
}, []);

return (
// Your app content
);
}
```

### Push Notifications (Config Plugin)

To enable push notifications, add the config plugin to your `app.json` or `app.config.js`:

```json
{
"expo": {
"plugins": [
[
"crisp-sdk-react-native",
{
"websiteId": "YOUR_WEBSITE_ID",
"notifications": {
"enabled": true,
"mode": "sdk-managed"
}
}
]
]
}
}
```

#### Plugin Options

| Option | Type | Default | Description |
| ----------------------- | -------------------------------- | --------------- | ---------------------------------------------------------------------------- |
| `websiteId` | `string` | - | Your Crisp Website ID. **Required** when notifications are enabled. |
| `notifications.enabled` | `boolean` | `false` | Enable push notifications for Crisp Chat. |
| `notifications.mode` | `"sdk-managed" \| "coexistence"` | `"sdk-managed"` | Notification handling mode. See [Coexistence Mode](#coexistence-mode) below. |

> [!IMPORTANT]
> The `websiteId` is **required** when `notifications.enabled` is `true`. The plugin will throw an error if it's missing.

#### What the Plugin Configures

**iOS:**

- Adds `remote-notification` to UIBackgroundModes
- Adds `aps-environment` entitlement for APNs
- Registers for remote notifications on app launch
- Forwards device token to Crisp SDK

**Android:**

- Adds `CrispNotificationService` to AndroidManifest
- Adds `firebase-messaging` dependency
- Configures Crisp SDK with websiteId

> [!NOTE]
> After enabling notifications, rebuild your app with `npx expo prebuild --clean` followed by `npx expo run:ios` or `npx expo run:android`.

#### Crisp Dashboard Configuration

Push notifications require additional setup in your Crisp Dashboard (APNs for iOS, Firebase for Android).

See the [Push Notifications Setup Guide](./docs/PUSH_NOTIFICATIONS.md) for detailed step-by-step instructions.

#### Coexistence Mode

By default, Crisp handles all push notification routing exclusively (`"sdk-managed"` mode). If your app uses another notification system (like `expo-notifications`, `@react-native-firebase/messaging`, or OneSignal), use `"coexistence"` mode to let both systems work together:

```json
{
"expo": {
"plugins": [
[
"crisp-sdk-react-native",
{
"websiteId": "YOUR_WEBSITE_ID",
"notifications": {
"enabled": true,
"mode": "coexistence"
}
}
]
]
}
}
```

In coexistence mode, the plugin:

- **Android**: Generates a chained `FirebaseMessagingService` that routes Crisp notifications to the Crisp SDK and delegates all others to `expo-notifications` (or Firebase directly)
- **iOS**: Implements a `UNUserNotificationCenterDelegate` that filters Crisp notifications and forwards the rest to the previous delegate (chain of responsibility)

**JS API for coexistence mode:**

```typescript
import {
registerPushToken,
isCrispPushNotification,
setShouldPromptForNotificationPermission,
} from "crisp-sdk-react-native";

// Register a push token obtained from your notification system
registerPushToken(expoPushToken);

// Check if a notification payload is from Crisp
const isCrisp = isCrispPushNotification(notificationData);

// Control whether Crisp auto-prompts for notification permissions (iOS only)
setShouldPromptForNotificationPermission(false);
```

**Listen for Crisp notifications in the foreground (iOS only):**

```typescript
import { useCrispEvents } from "crisp-sdk-react-native";

useCrispEvents({
onPushNotificationReceived: ({ title, body }) => {
console.log("Crisp notification:", title, body);
// Update badge count, show toast, log analytics, etc.
},
});
```

> [!NOTE]
> `onPushNotificationReceived` is currently **iOS only**. On Android, the Crisp SDK does not expose a foreground notification callback — notifications are handled entirely at the native `FirebaseMessagingService` level.

> [!NOTE]
> In coexistence mode, the native routing is automatic — you don't need to write JS filtering code. The JS API methods (`registerPushToken`, `isCrispPushNotification`) are optional utilities for advanced use cases.

---

## Usage Examples

### Open Chat

Display the Crisp chat widget:

```typescript
import { show, openChat } from "crisp-sdk-react-native";

// Opens the widget (remembers the last active tab)
show();

// Always opens on the Chat tab, regardless of the last active tab
openChat();
```

> [!NOTE]
> `openChat()` forces the Chat tab on **iOS only**. On Android, the native SDK always opens on the Chat tab by default, so `openChat()` and `show()` behave the same way.

### User Identification

Set user information to personalize the chat experience:

```typescript
import {
setUserEmail,
setUserNickname,
setUserPhone,
setUserAvatar,
setUserCompany,
setTokenId,
resetSession,
} from "crisp-sdk-react-native";

// After user logs in
function identifyUser(user) {
// Basic identification
setUserEmail(user.email);
setUserNickname(user.name);
setUserPhone(user.phone); // E.164 format recommended: "+1234567890"
setUserAvatar(user.avatarUrl);

// Set company information
setUserCompany({
name: "Acme Corporation",
url: "https://acme.com",
companyDescription: "Leading provider of innovative solutions",
employment: {
title: "Software Engineer",
role: "Engineering",
},
geolocation: {
country: "France",
city: "Paris",
},
});

// Enable session persistence across devices
setTokenId(user.id);
}

// On logout
function onLogout() {
setTokenId(null);
resetSession();
}
```

### Session Data

Store custom data visible to operators in the Crisp dashboard:

```typescript
import {
setSessionString,
setSessionBool,
setSessionInt,
setSessionSegment,
setSessionSegments,
getSessionIdentifier,
} from "crisp-sdk-react-native";

// Store different data types
setSessionString("plan", "premium");
setSessionBool("verified", true);
setSessionInt("loginCount", 42);

// Categorize users with segments
setSessionSegment("vip");

// Or set multiple segments at once
setSessionSegments(["premium", "early-adopter", "beta-tester"]);

// Replace all existing segments
setSessionSegments(["enterprise"], true);

// Get the current session identifier
const sessionId = await getSessionIdentifier();
console.log("Session ID:", sessionId);
```

### Event Tracking

Track user actions in the chat timeline:

```typescript
import {
pushSessionEvent,
pushSessionEvents,
CrispSessionEventColors,
} from "crisp-sdk-react-native";

// Track a single event
pushSessionEvent("Purchase completed", CrispSessionEventColors.GREEN);
pushSessionEvent("Payment failed", CrispSessionEventColors.RED);

// Track multiple events at once
pushSessionEvents([
{ name: "Viewed pricing page", color: CrispSessionEventColors.BLUE },
{ name: "Started free trial", color: CrispSessionEventColors.GREEN },
{ name: "Upgraded to Pro", color: CrispSessionEventColors.PURPLE },
]);
```

### Event Listeners

Subscribe to SDK events using the `useCrispEvents` hook:

```typescript
import { useState } from "react";
import { View, Button } from "react-native";
import { show, useCrispEvents } from "crisp-sdk-react-native";

function ChatScreen() {
const [unreadCount, setUnreadCount] = useState(0);

useCrispEvents({
onSessionLoaded: (sessionId) => {
console.log("Crisp session ready:", sessionId);
},
onChatOpened: () => {
console.log("Chat opened");
setUnreadCount(0); // Reset unread count
},
onChatClosed: () => {
console.log("Chat closed");
},
onMessageSent: (message) => {
console.log("User sent:", message.content);
},
onMessageReceived: (message) => {
console.log("Received:", message.content);
if (message.fromOperator) {
setUnreadCount((count) => count + 1);
}
},
});

return (

show()} />

);
}
```

### Show Messages

Display messages programmatically in the chat:

```typescript
import { showMessage } from "crisp-sdk-react-native";

// Simple text message
showMessage({
type: "text",
text: "Hello! How can I help you today?",
});

// File attachment
showMessage({
type: "file",
url: "https://example.com/document.pdf",
name: "Document.pdf",
mimeType: "application/pdf",
});

// Animation (GIF)
showMessage({
type: "animation",
url: "https://example.com/celebration.gif",
mimeType: "image/gif",
});

// Audio message
showMessage({
type: "audio",
url: "https://example.com/voice-note.mp3",
mimeType: "audio/mpeg",
duration: 15,
});

// Picker for user choice
showMessage({
type: "picker",
id: "satisfaction",
text: "How satisfied are you with our service?",
choices: [
{ value: "happy", label: "Very satisfied" },
{ value: "neutral", label: "Neutral" },
{ value: "sad", label: "Not satisfied" },
],
});

// Field for user input
showMessage({
type: "field",
id: "email",
text: "What's your email address?",
explain: "We'll send you updates",
required: true,
});

// Carousel with multiple items
showMessage({
type: "carousel",
text: "Check out our products",
targets: [
{
title: "Product A",
description: "Great for beginners",
imageUrl: "https://example.com/product-a.jpg",
actionUrl: "https://example.com/products/a",
},
{
title: "Product B",
description: "For power users",
imageUrl: "https://example.com/product-b.jpg",
actionUrl: "https://example.com/products/b",
},
],
});
```

### Helpdesk

Access your knowledge base:

```typescript
import { searchHelpdesk, openHelpdeskArticle } from "crisp-sdk-react-native";

// Open helpdesk search (automatically opens the chat)
searchHelpdesk();

// Open a specific article (automatically opens the chat)
openHelpdeskArticle({
id: "getting-started",
locale: "en",
title: "Getting Started", // Optional
category: "Onboarding", // Optional
});
```

### Bot Scenarios

Trigger automated conversation flows:

```typescript
import { runBotScenario } from "crisp-sdk-react-native";

// Start a bot scenario configured in your Crisp dashboard
runBotScenario("welcome-flow");
```

### Debug Logging

Enable native SDK logging to help debug integration issues:

```typescript
import {
setLogLevel,
CrispLogLevel,
useCrispEvents,
} from "crisp-sdk-react-native";

// Set the minimum log level (default: WARN)
setLogLevel(CrispLogLevel.DEBUG);

// Listen to log messages from the native SDK
useCrispEvents({
onLogReceived: (log) => {
console.log(`[Crisp] [${log.level}] ${log.tag}: ${log.message}`);
},
});
```

Available log levels (from most to least verbose):

| Level | Value | Description |
| --------- | ----- | ------------------------------ |
| `VERBOSE` | 0 | Most verbose, all log messages |
| `DEBUG` | 1 | Debug information |
| `INFO` | 2 | Informational messages |
| `WARN` | 3 | Warnings (default) |
| `ERROR` | 4 | Error messages only |
| `ASSERT` | 5 | Critical assertion failures |

> [!NOTE]
> Set the log level **after** calling `configure()`. Only logs at or above the configured level are emitted to the `onLogReceived` callback.

---

## API Reference

### Configuration Methods

| Method | Description | Parameters | Return |
| ---------------------- | ---------------------------------------------------------------------------- | ------------------------- | ------ |
| `configure(websiteId)` | Initialize the SDK with your Website ID. Must be called once at app startup. | `websiteId: string` | `void` |
| `setTokenId(tokenId)` | Set a token for session persistence across app reinstalls and devices. | `tokenId: string \| null` | `void` |

### Logger Methods

| Method | Description | Parameters | Return |
| -------------------- | -------------------------------------------------------------------------------------------------------------- | ---------------------- | ------ |
| `setLogLevel(level)` | Set the minimum log level for native SDK logging. Logs at or above this level are emitted via `onLogReceived`. | `level: CrispLogLevel` | `void` |

### User Information Methods

| Method | Description | Parameters | Return |
| --------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------- | ------ |
| `setUserEmail(email, signature?)` | Set the user's email address. Optional HMAC signature for verification. | `email: string, signature?: string \| null` | `void` |
| `setUserNickname(name)` | Set the user's display name in the chat. | `name: string` | `void` |
| `setUserPhone(phone)` | Set the user's phone number. E.164 format recommended. | `phone: string` | `void` |
| `setUserAvatar(url)` | Set the user's avatar image URL. | `url: string` | `void` |
| `setUserCompany(company)` | Set the user's company information. | `company: Company` | `void` |

### Session Data Methods

| Method | Description | Parameters | Return |
| ------------------------------------------ | -------------------------------------------------------------------------- | ----------------------------------------- | ------------------------- |
| `setSessionString(key, value)` | Store a custom string value in session data. | `key: string, value: string` | `void` |
| `setSessionBool(key, value)` | Store a custom boolean value in session data. | `key: string, value: boolean` | `void` |
| `setSessionInt(key, value)` | Store a custom integer value in session data. | `key: string, value: number` | `void` |
| `setSessionSegment(segment)` | Set a single segment to categorize the user. | `segment: string` | `void` |
| `setSessionSegments(segments, overwrite?)` | Set multiple segments. If `overwrite` is true, replaces existing segments. | `segments: string[], overwrite?: boolean` | `void` |
| `getSessionIdentifier()` | Get the current session identifier. | - | `Promise` |

### Event Tracking Methods

| Method | Description | Parameters | Return |
| ------------------------------- | ------------------------------------------------- | ---------------------------------------------- | ------ |
| `pushSessionEvent(name, color)` | Track a single event in the user's chat timeline. | `name: string, color: CrispSessionEventColors` | `void` |
| `pushSessionEvents(events)` | Track multiple events at once. | `events: SessionEvent[]` | `void` |

### Session Management

| Method | Description | Parameters | Return |
| ---------------- | --------------------------------------------------------- | ---------- | ------ |
| `resetSession()` | Clear the current session and start a fresh conversation. | - | `void` |

### UI Methods

| Method | Description | Parameters | Return |
| ------------------------------ | ------------------------------------------------------- | --------------------------------- | ------ |
| `show()` | Open the Crisp chat widget (last active tab). | - | `void` |
| `openChat()` | Open the Crisp chat widget always on the Chat tab (iOS only, see note below). | - | `void` |
| `searchHelpdesk()` | Open the helpdesk search interface and the chat widget. | - | `void` |
| `openHelpdeskArticle(options)` | Open a specific helpdesk article and the chat widget. | `options: HelpdeskArticleOptions` | `void` |
| `runBotScenario(scenarioId)` | Trigger an automated bot scenario. | `scenarioId: string` | `void` |

### Push Notification Methods (Coexistence Mode)

| Method | Description | Parameters | Return |
| --------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------ | --------- |
| `registerPushToken(token)` | Register a push token (FCM/APNs) with Crisp. | `token: string` | `void` |
| `isCrispPushNotification(data)` | Check if a notification payload is from Crisp. | `data: Record` | `boolean` |
| `setShouldPromptForNotificationPermission(enabled)` | Control auto-prompting for notification permissions (iOS only, no-op on Android). | `enabled: boolean` | `void` |

### Message Methods

| Method | Description | Parameters | Return |
| ---------------------- | --------------------------------------------------- | ------------------------- | ------ |
| `showMessage(content)` | Display a message as operator in the local chatbox. | `content: MessageContent` | `void` |

### React Hook

| Hook | Description | Parameters | Return |
| --------------------------- | ----------------------------------------------- | -------------------------------- | ------ |
| `useCrispEvents(callbacks)` | Subscribe to SDK events with automatic cleanup. | `callbacks: CrispEventCallbacks` | `void` |

### Utility Functions

| Function | Description | Parameters | Return |
| ----------------- | ---------------------------------------------- | ---------- | -------- |
| `getSDKVersion()` | Get the crisp-sdk-react-native version string. | - | `string` |

---

## TypeScript Types

### Core Interfaces

#### Company

```typescript
interface Company {
name: string; // Required: Company name
url?: string; // Company website URL
companyDescription?: string; // Brief company description
employment?: Employment; // User's job details
geolocation?: Geolocation; // Company location
}
```

#### Employment

```typescript
interface Employment {
title?: string; // Job title (e.g., "Software Engineer")
role?: string; // Department/role (e.g., "Engineering")
}
```

#### Geolocation

```typescript
interface Geolocation {
country?: string; // Country name or ISO code
city?: string; // City name
}
```

#### SessionEvent

```typescript
interface SessionEvent {
name: string; // Event name
color: CrispSessionEventColors; // Event color
}
```

### Message Types

#### CrispMessage

```typescript
interface CrispMessage {
content: string; // Message text
timestamp: number; // Unix timestamp (ms)
fromOperator: boolean; // true if from operator
fingerprint: string; // Unique message ID
isMe: boolean; // true if sent by current user
origin: CrispMessageOrigin; // "local" | "network" | "update"
user?: CrispUser; // Sender information
}
```

#### CrispUser

```typescript
interface CrispUser {
nickname?: string; // Display name
userId?: string; // Unique identifier
avatar?: string; // Avatar URL
}
```

### Message Content Types

The `showMessage` method accepts these content types:

#### TextMessageContent

```typescript
{ type: "text", text: string }
```

#### FileMessageContent

```typescript
{ type: "file", url: string, name: string, mimeType: string }
```

#### AnimationMessageContent

```typescript
{ type: "animation", url: string, mimeType: string }
```

#### AudioMessageContent

```typescript
{ type: "audio", url: string, mimeType: string, duration: number }
```

#### PickerMessageContent

```typescript
{
type: "picker",
id: string,
text: string,
choices: Array<{ value: string, label: string, selected?: boolean }>
}
```

#### FieldMessageContent

```typescript
{ type: "field", id: string, text: string, explain?: string, required?: boolean }
```

#### CarouselMessageContent

```typescript
{
type: "carousel",
text: string,
targets: Array<{
title: string,
description?: string,
imageUrl?: string,
actionUrl?: string
}>
}
```

### Event Callbacks

```typescript
interface CrispEventCallbacks {
onSessionLoaded?: (sessionId: string) => void;
onChatOpened?: () => void;
onChatClosed?: () => void;
onMessageSent?: (message: CrispMessage) => void;
onMessageReceived?: (message: CrispMessage) => void;
onPushNotificationReceived?: (notification: PushNotificationPayload) => void; // iOS only
onLogReceived?: (log: CrispLogEntry) => void;
}
```

### Event Payload Types

These types are used internally by the event system:

```typescript
// Payload for onSessionLoaded callback
interface SessionLoadedPayload {
sessionId: string;
}

// Payload for onMessageSent and onMessageReceived callbacks
interface MessagePayload {
message: CrispMessage;
}

// Empty payload for onChatOpened and onChatClosed callbacks
type EmptyPayload = Record;

// Payload for onPushNotificationReceived callback (iOS only)
interface PushNotificationPayload {
title: string;
body: string;
}

// Payload for onLogReceived callback
interface LogReceivedPayload {
log: CrispLogEntry;
}

// Log entry from the native SDK
interface CrispLogEntry {
level: CrispLogLevel; // The log level
tag: string; // Log category/source
message: string; // Log message content
}

// Message origin type
type CrispMessageOrigin = "local" | "network" | "update";
```

### Helper Types

Types used within message content interfaces:

```typescript
// Choice option for picker messages
interface PickerChoice {
value: string; // Unique identifier
label: string; // Display text
selected?: boolean; // Pre-selected state
}

// Target item for carousel messages
interface CarouselTarget {
title: string; // Item title
description?: string; // Item description
imageUrl?: string; // Image URL
actionUrl?: string; // Action URL when tapped
}
```

### Enums

#### CrispSessionEventColors

| Value | Color | Suggested Use |
| ------------ | ------ | ------------------------------------ |
| `RED` (0) | Red | Errors, failures, critical events |
| `ORANGE` (1) | Orange | Warnings, attention needed |
| `YELLOW` (2) | Yellow | Informational highlights |
| `GREEN` (3) | Green | Success, completion, positive events |
| `BLUE` (4) | Blue | Informational, neutral events |
| `PURPLE` (5) | Purple | Special, premium-related events |
| `PINK` (6) | Pink | Social, engagement events |
| `BROWN` (7) | Brown | Historical, archive events |
| `GREY` (8) | Grey | Secondary, low-priority events |
| `BLACK` (9) | Black | System, administrative events |

#### CrispLogLevel

| Value | Description |
| ------------- | --------------------------------------- |
| `VERBOSE` (0) | Most verbose; includes all log messages |
| `DEBUG` (1) | Debug information for development |
| `INFO` (2) | Informational messages |
| `WARN` (3) | Warnings (default level) |
| `ERROR` (4) | Error messages only |
| `ASSERT` (5) | Critical assertion failures |

---

## Troubleshooting

### "Expo Go is not supported"

The Crisp SDK requires native modules. Use a development build instead:

```bash
npx expo run:ios
# or
npx expo run:android
```

### Chat not appearing after `show()`

Ensure you've called `configure()` with a valid Website ID before calling `show()`.

### Push notifications not working

1. Verify the config plugin is properly configured in `app.json`
2. Rebuild with `npx expo prebuild --clean`
3. Ensure your Crisp dashboard has push notifications enabled
4. For iOS: Verify APNs certificates are configured in Crisp dashboard
5. For Android: Verify Firebase is properly configured

### Session data not persisting

Use `setTokenId()` with a unique user identifier to enable session persistence across app reinstalls and devices.

---

## Example Apps

Two fully functional example apps are included in the repository to help you get started:

| App | Directory | Description |
| --------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| **Expo** | [`/example`](./example) | Expo Router app with push notifications (coexistence mode with `expo-notifications`), event listeners, and all SDK features |
| **Bare React Native** | [`/bare-example`](./bare-example) | Bare React Native CLI app demonstrating integration without the Expo managed workflow |

Both apps are pre-configured and ready to run — just add your Website ID and follow the setup instructions in each directory.

---

## Resources

- [Crisp SDK Overview](https://crisp.chat/en/sdk/) — All available Crisp SDKs
- [React Native SDK Page](https://crisp.chat/en/sdk/react-native/) — Product page for this SDK
- [Crisp Help Center](https://help.crisp.chat/)
- [Crisp Developer Documentation](https://docs.crisp.chat/)
- [iOS SDK Documentation](https://docs.crisp.chat/guides/chatbox-sdks/ios-sdk/)
- [Android SDK Documentation](https://docs.crisp.chat/guides/chatbox-sdks/android-sdk/)

## Contributing

Issues and pull requests are welcome on [GitHub](https://github.com/crisp-im/crisp-sdk-react-native/issues).

## License

MIT - See [LICENSE](./LICENSE) for details.