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

# SDK React Native

> Push, in-app et Live Activities dans une application Expo, en une ligne d’initialisation.

Le SDK demande l’autorisation, enregistre l’appareil, affiche les notifications app ouverte, remonte ouvertures et clics, et renouvelle le jeton. L’application n’embarque **aucun fichier de configuration** : ni `google-services.json`, ni `GoogleService-Info.plist`. Tout se règle dans le dashboard et le SDK le lit au démarrage.

## Avant de commencer

1. **Un development build** : Expo Go n’embarque pas le module natif du SDK.
2. **L’application configurée** dans le dashboard, dans le bon environnement (compte de service Firebase pour Android, clé APNs `.p8` pour iOS). Voir [Notifications push](https://docs.dexnotify.com/push/introduction.md).
3. **Une clé SDK** (portée `sdk:device`), préréglage « Clé SDK », et l’identifiant de l’application.
4. iOS : un appareil physique — le simulateur ne reçoit pas de push distant.

## Installation

Le paquet est publié sur GitHub Packages. Créez un jeton GitHub classique avec la seule portée `read:packages`, puis dans le `.npmrc` de l’application :

```ini theme={null}
@dexchange-group:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
```

```bash theme={null}
npx expo install @dexchange-group/dexnotify-react-native
```

Puis le plugin Expo :

```js app.config.js theme={null}
plugins: [
  ["@dexchange-group/dexnotify-react-native", { mode: IS_DEV ? "development" : "production" }],
],
```

Un nouveau build natif est nécessaire après l’ajout du paquet.

## Initialiser

```ts theme={null}
import { DexNotify } from "@dexchange-group/dexnotify-react-native";

// Au lancement, une fois, sans l'attendre.
void DexNotify.initialize({
  baseUrl: "https://api.dexnotify.com/api",
  apiKey: process.env.EXPO_PUBLIC_DEXNOTIFY_API_KEY!,
  applicationId: process.env.EXPO_PUBLIC_DEXNOTIFY_APP_ID!,
  onError: (error) => console.warn("[dexnotify]", error.code, error.message),
});

// À la connexion : l'appareil devient celui de ce client.
void DexNotify.login(customerId);

// À la déconnexion.
void DexNotify.logout();
```

`initialize` demande l’autorisation (`requestPermission: false` pour la demander plus tard). **Aucune méthode ne rejette** : les échecs passent par `onError`.

## Utilisateurs

Avant `login`, l’utilisateur est **anonyme** : il reçoit les envois à tous les abonnés et peut porter des tags. `login` d’un External ID inconnu le promeut en gardant ses tags ; `logout` confie l’appareil à un nouvel anonyme.

```ts theme={null}
DexNotify.User.getExternalId();
void DexNotify.User.addTag("plan", "gold");
void DexNotify.User.addTags({ niveau: 3, ville: "Dakar" });
void DexNotify.User.removeTag("ville");
void DexNotify.User.setLanguage("wo");
```

## Notifications

```ts theme={null}
const granted = await DexNotify.Notifications.requestPermission(true);
DexNotify.Notifications.addEventListener("click", ({ notificationId, deepLink, data }) => {
  // …
});
DexNotify.Notifications.addEventListener("foregroundWillDisplay", (event) => {
  if (event.getNotification().data.ecran === "transfert") event.preventDefault();
});
```

Le lien profond est ouvert automatiquement (`openDeepLinks: false` pour s’en charger).

```ts theme={null}
const { pushSubscription } = DexNotify.User;
void pushSubscription.optOut(); // reste enregistré, ne reçoit plus rien
void pushSubscription.optIn();
```

## Événements et conversions

```ts theme={null}
DexNotify.User.trackEvent("transfert_effectue", { montant: 25000 });
DexNotify.Session.addOutcome("inscription");
DexNotify.Session.addOutcomeWithValue("achat", 5000);
```

## Consentement

```ts theme={null}
DexNotify.setConsentRequired(true); // avant initialize
DexNotify.setConsentGiven(true);    // quand l'utilisateur accepte
```

Tant que le consentement exigé manque, rien ne quitte l’appareil.

## Messages in-app

Montez l’hôte **une fois**, à la racine de l’app :

```tsx theme={null}
import { DexNotifyInAppHost } from "@dexchange-group/dexnotify-react-native";

export default function RootLayout() {
  return (
    <>
      <Stack />
      <DexNotifyInAppHost />
    </>
  );
}
```

```ts theme={null}
DexNotify.InAppMessages.addTrigger("ecran", "transfert");
DexNotify.InAppMessages.setPaused(true); // par exemple pendant un paiement
DexNotify.InAppMessages.addEventListener("click", ({ messageId, elementId, action }) => {});
```

Les messages HTML demandent `react-native-webview` (`npx expo install react-native-webview`).

## Live Activities (iOS)

```ts theme={null}
if (DexNotify.LiveActivities.isSupported()) {
  await DexNotify.LiveActivities.startDefault(
    "transfert-8812",
    { beneficiaire: "Awa Diop" },
    { etape: "En cours", montant: 25000 },
  );
}
```

Avec `liveActivities: true` dans les options du plugin, et une cible widget qui dessine l’activité. Les mises à jour se pilotent ensuite par l’[API](https://docs.dexnotify.com/push/live-activities.md).

## En cas d’échec

| Situation | Ce que fait le SDK |
| - | - |
| Panne réseau, délai dépassé, `5xx` | jusqu’à deux reprises, repli exponentiel |
| `401`, `403`, `422` | aucun renvoi |
| Échec définitif | `onError`, et la méthode rend `undefined` |

## La clé embarquée

Une clé dans une application mobile est extractible. Émettez-la avec la **seule** portée `sdk:device` : chaque route qu’elle ouvre exige le jeton de l’appareil, et elle ne peut ni lire l’audience ni réécrire un profil.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.