> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cello.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Cello for React Native

The Cello React Native wrapper allows you to use Cello for iOS and Cello for Android in your React Native apps. With a plug-n-play mobile component, your users can easily share their invite link with their friends and network using mobile sharing options convenient for them, receive rewards and get paid out.

## Installation

A basic installation takes around 15 minutes, but will take a little longer if you want to customize the way the Cello Referral Component is launched.

**Compatibility**

* The Cello React Native wrapper supports React Native **0.59** and above.
* Cello for iOS supports **iOS 15+**.
* Cello for Android supports **API 21+**.

### Install Cello

```bash theme={null}
yarn add @getcello/cello-react-native
# or
npm install @getcello/cello-react-native
```

### Android Setup

#### Automatic Linking (RN v0.60+)

Library is automatically linked after installation.

#### React Native v0.59 (Automatic Linking)

```bash theme={null}
react-native link @getcello/cello-react-native
```

#### React Native v0.59 (Manual Linking)

**`android/settings.gradle`**

```groovy theme={null}
include ':cello-react-native'
project(':cello-react-native').projectDir = new File(rootProject.projectDir, '../node_modules/@getcello/cello-react-native/android')
```

**`android/app/build.gradle`**

```groovy theme={null}
dependencies {
  implementation project(':cello-react-native')
}
```

### Android Initialization

Update your `MainApplication.java`:

```java theme={null}
import com.celloreactnative.CelloReactNativeModule;

@Override
public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    CelloReactNativeModule.initialize(this, "productId", "token");
}
```

Also include internet permission in `android/app/src/main/AndroidManifest.xml`:

```xml theme={null}
<uses-permission android:name="android.permission.INTERNET" />
```

### iOS Setup

#### Automatic Linking (RN v0.60+)

Library links automatically after `pod install`.

#### Manual Linking (RN v0.59)

1. Open `.xcworkspace` or `.xcodeproj`.
2. Insert the `CelloSDK.xcframework` into your project (enable "Copy items if needed").
3. In target settings, set it to **Embed & Sign** under *Frameworks, Libraries, and Embedded Content*.

For additional information on iOS manual linking please refer to the [**React Native developer docs**](https://reactnative.dev/docs/linking-libraries-ios).

### iOS Initialization

In `AppDelegate.m`, add:

```objc theme={null}
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
// ...
#import <CelloReactNative.h> // <-- Add This
```

Next, in the method `didFinishLaunchingWithOptions` you'll need to initialize Cello. Add the snippet below using the `productId` and `token`

```
// ...
  self.window.rootViewController = rootViewController;

  [CelloReactNative initialize:for@"productId" with:@"token"]; // <-- Add this (Remember to replace strings with your product id and token)

  return YES;
  }
```

## Choose an Environment

In your Cello SDK setup, you have the flexibility to select the environment in which your application will run. This feature is especially useful for different stages of development, such as testing in a development or staging environment before going live in production. The available environments are:

* `prod` (Production) *(default)*
* `sandbox` (Sandbox)

For iOS follow [**Cello for iOS configurational steps**](https://docs.cello.so/docs/cello-for-ios#choose-an-environment)

For Android follow Cello for [**Android configurational steps**](https://docs.cello.so/docs/cello-for-android#choose-an-environment)

## Using Cello with Expo

If you are using Expo, you can use the built-in plugin. After installing the **@getcello/cello-react-native** package, add the [**config plugin**](https://docs.expo.io/guides/config-plugins/) to the `plugins` array of your `app.json` or `app.config.js`:

```json theme={null}
{
  "expo": {
    "plugins": ["@getcello/cello-react-native"]
  }
}
```

The plugin provides props to set environment. Every time you change the props or plugins, you'll need to rebuild (and `prebuild`) the native app. If no extra properties are added, defaults will be used.

* `env` (*string*): Set to your desired environment, such as `prod`, `sandbox`. Optional. Defaults to `prod`.

```json theme={null}
{
  "expo": {
    "plugins": [
      [
        "@getcello/cello-react-native",
        {
          "env": "sandbox"
        }
      ]
    ]
  }
}
```

Next, rebuild your app as described in the [**"Adding custom native code"**](https://docs.expo.io/workflow/customizing/) guide.

## Customize the Cello Referral Component

The Cello React Native allows for various levels of customization to better fit into your app's design and flow. One of the main components you might want to customize is the [**Referral component**](https://docs.cello.so/docs/component-overview)

### Choose Your Launcher

The library provides two ways to launch the Referral component:

**Default launcher**

If you choose to go with the default launcher, you can call the `showFab()` method from the Cello library to present a Floating Action Button (FAB) within your app. This FAB is pre-styled but may not perfectly match your app's look and feel.

```js theme={null}
import Cello from '@getcello/cello-react-native';
Cello.showFab();
```

**Custom launcher**

If the default launcher does not fit your needs, you can implement your own custom launcher. This could be any UI element like a button, menu item, or even a gesture. To open the Referral component using a custom launcher, you can call `Cello.openWidget()`.

```js theme={null}
import Cello from '@getcello/cello-react-native';

const MyButton = () => {
  return <Button onPress={() => Cello.openWidget()}>Open Referral</Button>;
};
```

## React Native API

### `Cello.initialize(InitializeOptions): Promise<Configuration>`

Initializes the Cello referral component.

### InitializeOptions

| Property           | Type               | Required | Description                               |
| ------------------ | ------------------ | -------- | ----------------------------------------- |
| productId          | string             | yes      | Your product ID from Cello Portal         |
| token              | string             | yes      | User authentication token                 |
| productUserDetails | ProductUserDetails | no       | User details object (see below)           |
| language           | string             | no       | Initial language of the widget            |
| themeMode          | string             | no       | Initial theme mode: `"light"` or `"dark"` |

### ProductUserDetails

Optional object with user information:

| Property  | Type   | Description          |
| --------- | ------ | -------------------- |
| firstName | string | User's first name    |
| lastName  | string | User's last name     |
| fullName  | string | User's full name     |
| email     | string | User's email address |

```ts theme={null}
Cello.initialize({
  productId: 'your-product-id',
  token: 'your-token',
  productUserDetails: {
    firstName: 'John',
    lastName: 'Doe',
    fullName: 'John Doe',
    email: 'john.doe@example.com',
  },
  language: 'de',
  themeMode: 'light',
});
```

### `Cello.showFab(): void`

Shows the default Cello button that launches the Referral Component

```ts theme={null}
Cello.showFab();
```

### `Cello.hideFab(): void`

Hides the default Cello button that launches the Referral Component

```ts theme={null}
Cello.hideFab();
```

### `Cello.openWidget(): void`

Opens the referral component.

```ts theme={null}
Cello.openWidget();
```

### `Cello.hideWidget(): void`

Hides the referral component.

```ts theme={null}
Cello.hideWidget();
```

### `Cello.getActiveUcc(): Promise<{ ucc: string; inviteLink: string; } | null>`

A method to get an active `ucc` and invite link for the currently logged in user.

```ts theme={null}
const data = await Cello.getActiveUcc();
```

### `Cello.changeLanguage(langCode: string): void`

A method to change the language of the Referral component at runtime without re-initialising it.

```ts theme={null}
Cello.changeLanguage('de');
```

### `Cello.setThemeMode(themeMode: string): void`

A method to change the theme mode of the Referral component at runtime without re-initialising it.

```ts theme={null}
Cello.setThemeMode('dark');
```

**Parameters:**

* `themeMode` (*string*): The theme mode to set. Valid values are `"light"` or `"dark"`.

### `Cello.shutdown(): void`

Shuts down connection to Cello and unmounts the component

```ts theme={null}
Cello.shutdown();
```

***

## Error Handling

### Promise rejection codes

| Code                      | Platform(s)   | Trigger                                          | Typical causes                                                          |
| ------------------------- | ------------- | ------------------------------------------------ | ----------------------------------------------------------------------- |
| `InitializationError`     | iOS & Android | `Cello.initialize` completes with native failure | Invalid/empty product ID or token, network issues, bad environment      |
| `InitializationException` | Android       | Unexpected exception inside `Cello.initialize`   | Activity finishing, SDK not linked correctly, runtime crash             |
| `ActivityError`           | Android       | `Cello.initialize` without an active Activity    | Initialization triggered too early (e.g. before React root ready)       |
| `TokenUpdateError`        | iOS           | `Cello.updateToken` failure                      | Token expired/invalid, network errors                                   |
| `LanguageChangeError`     | iOS           | `Cello.changeLanguage` failure                   | Unsupported language code, network errors                               |
| `ThemeModeChangeError`    | iOS           | `Cello.setThemeMode` failure                     | Invalid theme mode value, network errors                                |
| `UnavailableError`        | iOS           | Feature requires iOS 14+                         | Device running \< iOS 14 when calling token, language, or theme updates |
| `NO_ACTIVE_UCC`           | iOS           | `Cello.getActiveUcc` with no active referral     | User has not generated an invite yet                                    |
| `UCC_ERROR`               | Android       | `Cello.getActiveUcc` threw                       | SDK not initialized, network or serialization errors                    |
| `CAMPAIGN_CONFIG_ERROR`   | Android       | `Cello.getCampaignConfig` threw                  | SDK not initialized, configuration not ready                            |
| `LINKING_ERROR`           | JavaScript    | Module not linked                                | Pod install missing, app not rebuilt, using Expo Go                     |

> **Tip:** The React Native bridge rejects promises with the objects above. Inspect `error.code`, `error.message`, and (on iOS) `error.nativeStackIOS` for extra context.

### Common error scenarios

#### 1. Initialization promise rejected

**Symptoms:** `InitializationError` or `InitializationException` in the catch block.

**Fix:** Validate credentials, confirm network connectivity, and ensure you selected the right environment (`prod` vs `sandbox`). Compare native logs with the [iOS](./ios.md#error-handling) and [Android](./android.md#error-handling) error references for detailed native codes.

#### 2. Module not linked (`LINKING_ERROR`)

**Symptoms:** Error thrown immediately when importing `@getcello/cello-react-native`.

**Fix:** Run `pod install` inside `ios`, rebuild the app, and ensure you are not running inside Expo Go. For older RN versions (`0.59`), double-check manual linking steps.

#### 3. UI calls before initialization finishes

Calling `Cello.showFab()`, `Cello.openWidget()`, or similar before the SDK is ready triggers native console warnings such as `"Error: showFab() called before initialization."`. Track initialization state in JavaScript and gate UI interactions until `Cello.initialize` resolves.

#### 4. Platform feature limitations

`Cello.changeLanguage` and `Cello.setThemeMode` require iOS 14+. On older devices the bridge rejects with `UnavailableError`. Guard these calls with a platform/version check.

### Error handling best practices

**`1. Wrap initialization in try/catch:`**

```ts theme={null}
import { Alert } from 'react-native';
import Cello from '@getcello/cello-react-native';

async function bootstrapCello() {
  try {
    if (!productId.trim() || !token.trim()) {
      throw new Error('Missing credentials');
    }

    const config = await Cello.initialize({
      productId,
      token,
      productUserDetails,
    });

    setCelloReady(true);
    console.log('[Cello] Initialized', config);
  } catch (error: any) {
    console.warn('[Cello] Initialization failed', error);
    Alert.alert(
      'Referrals unavailable',
      'Please check your connection and try again.'
    );
  }
}
```

**2. Delay UI interactions:** Only call `Cello.showFab()` or `Cello.openWidget()` after a successful initialization. Keep a dedicated `isCelloReady` state flag in your components.

**3. Retry on transient errors:** For recoverable failures (network timeouts, `InitializationError`), schedule a retry with exponential or linear backoff. Limit retries to avoid looping endlessly.

**4. Log error details:** Capture `error.code`, `error.message`, and relevant native stack traces in your logging/monitoring solution to help support diagnose issues quickly.
