React Native Integration

Overview

Instructions to integrate the Appnomix Commerce SDK with your React Native project for iOS and Android.

You can also explore how the SDK is integrated in our Appnomix React Native Sample.

For any questions regarding the integration, please contact [email protected].

Getting Started

Minimum requirements

  • iOS
    • iOS version 15
    • Xcode 15
  • Android
    • minSDK version 5.0 (API 21)
    • Android compileSDK version 15 (API 35)
    • Java 17
  • React Native 0.83+
  • Node.js 18+

Installing the SDK

Follow the instructions below to setup the Appnomix Commerce SDK in your existing React Native project.

1. Install the npm package

# From your project directory
npm install github:NomixGroup/react-native-appnomix-commerce

2. iOS Setup

For iOS, run the setup script that automates the Xcode project configuration.

Create a config file at ios/appnomix.config:

cat > ios/appnomix.config << 'EOF'
PROJECT_PATH="."
APP_GROUPS_NAME="group.com.yourapp.shared"
LOGO_PNG_PATH="../assets/logo.png"
EOF
  • PROJECT_PATH — Path to the iOS project directory containing your .xcodeproj (relative to the config file). Use "." if the config file is in the same directory.
  • APP_GROUPS_NAME — Shared App Group identifier used for communication between your app and the Safari Extension. Must match the App Group configured in your Apple Developer account.
  • LOGO_PNG_PATH — Path to your app's logo (relative to config file). Used as the Safari Extension icon in various sizes. Square PNG recommended.

Then run:

# From your project's ios directory
cd ios
pod install
bash ../node_modules/react-native-appnomix-commerce/ios/SetupXcode.sh

Important: You must configure App Groups for both your main app and the Safari extension targets. See Configuring App Groups.

3. Android Setup

The Appnomix Commerce SDK dependency is included automatically via the npm package. You only need to enable Java 8+ API desugaring in your android/app/build.gradle:

android {
  compileOptions {
    coreLibraryDesugaringEnabled = true
  }
}

dependencies {
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}

Starting the SDK

Initialize the SDK and launch onboarding in your app:

import { useEffect, useState } from 'react';
import { Button, DeviceEventEmitter, Text, View } from 'react-native';
import {
  initialize,
  registerEventListener,
  showOnboarding,
  trackOfferDisplay,
  isOnboardingAvailable,
  isAccessibilityServiceEnabled
} from 'react-native-appnomix-commerce';

const ONBOARDING_EVENT = 'OnboardingEvent';

// Initialize SDK at app startup (outside component)
initialize(
  '_YOUR_APPNOMIX_CLIENT_ID_',
  '_YOUR_APPNOMIX_AUTH_TOKEN_',
  'group.com.yourapp.shared', // iOS App Group (required for iOS)
  'yourapp://',               // iOS URL Scheme (optional)
  null                        // Language: 'en', 'de', or null for system
);

registerEventListener(ONBOARDING_EVENT);

export default function App() {
  const [onboardingState, setOnboardingState] = useState<string>('Not started');

  useEffect(() => {
    // Listen for onboarding events
    const subscription = DeviceEventEmitter.addListener(
      ONBOARDING_EVENT,
      (event: string) => {
        console.log('Onboarding event:', event);
        setOnboardingState(event);

        switch (event) {
          case 'ONBOARDING_STARTED':
            // User started the onboarding flow
            break;
          case 'ONBOARDING_FINISHED':
            // User completed onboarding (extension installed / permission granted)
            break;
          case 'ONBOARDING_ABANDONED':
            // User cancelled the onboarding
            break;
        }
      }
    );

    return () => subscription.remove();
  }, []);

  const handleStartOnboarding = () => {
    // Track that the offer CTA was displayed
    trackOfferDisplay('main_screen');

    // Launch onboarding if available
    if (isOnboardingAvailable()) {
      showOnboarding('');
    }
  };

  return (
    <View>
      <Button title="Start Onboarding" onPress={handleStartOnboarding} />
      <Text>Status: {onboardingState}</Text>
    </View>
  );
}

initialize Parameters

ParameterTypePlatformDescription
clientIdstringBothYour Appnomix client ID. Contact [email protected] to obtain.
authTokenstringBothYour Appnomix authentication token. Contact [email protected] to obtain.
iOSAppGroupNamestringiOS onlyApp Group identifier (e.g., group.com.yourapp.shared). Required for Safari extension communication.
iOSAppURLSchemestringiOS onlyCustom URL scheme for your app (e.g., yourapp://). Optional.
languagestring | nullBothUI language: 'en' for English, 'de' for German, or null for system default.

Tracking the CTA and Installation

Event Tracking

Use registerEventListener to receive onboarding lifecycle events:

import { DeviceEventEmitter } from 'react-native';
import { registerEventListener } from 'react-native-appnomix-commerce';

const ONBOARDING_EVENT = 'OnboardingEvent';
registerEventListener(ONBOARDING_EVENT);

// In your component
useEffect(() => {
  const subscription = DeviceEventEmitter.addListener(ONBOARDING_EVENT, (event) => {
    switch (event) {
      case 'ONBOARDING_STARTED':
        // Onboarding screen displayed
        break;
      case 'ONBOARDING_FINISHED':
        // Extension installed (iOS) or Accessibility enabled (Android)
        break;
      case 'ONBOARDING_ABANDONED':
        // User cancelled onboarding
        break;
    }
  });

  return () => subscription.remove();
}, []);

Track Offer Display

Call trackOfferDisplay whenever you show the Appnomix CTA to the user:

import { trackOfferDisplay } from 'react-native-appnomix-commerce';

// When displaying the offer
trackOfferDisplay('offers_screen');
trackOfferDisplay('special_promotion');
trackOfferDisplay('app_start');

Customize Onboarding Screen

Pass a JSON string to showOnboarding to customize the onboarding UI:

const customization = JSON.stringify({
  backgroundColor: '#FFFFFF',
  primaryColor: '#007AFF',
  // ... other customization options
});

showOnboarding(customization);

You can use the Appnomix UI Configurator to generate the customization JSON.

Update Safari Extension Icon (iOS)

Replace the logo.png file referenced in your appnomix.config with your app's logo. Recommended size: 512x512 pixels.

Changing the Language

Pass the language code as the last parameter to initialize:

// English
initialize(clientId, authToken, appGroup, urlScheme, 'en');

// German
initialize(clientId, authToken, appGroup, urlScheme, 'de');

// System default
initialize(clientId, authToken, appGroup, urlScheme, null);

Platform-Specific Notes

iOS

  • The SDK integrates a Safari Web Extension that detects shopping websites
  • Requires App Groups capability for app-extension communication
  • User must enable the Safari extension in Settings > Safari > Extensions

Android

  • The SDK uses Android Accessibility Service to track browser interactions
  • Currently supports Google Chrome browser
  • Requires additional Play Console disclosure for Accessibility Service usage
  • Uses android.permission.BIND_ACCESSIBILITY_SERVICE

API Reference

FunctionDescription
initialize(clientId, authToken, iOSAppGroupName, iOSAppURLScheme, language)Initializes the SDK with your credentials and configuration. Call once at app startup.
registerEventListener(eventName)Registers a listener for onboarding lifecycle events. Use with DeviceEventEmitter.
isOnboardingAvailable()Checks if the onboarding configuration is initialized, and the onboarding can be started.
isAccessibilityServiceEnabled()Returns true if Android Accessibility Service is enabled. Always returns true on iOS.
showOnboarding(customizationJson)Launches the onboarding flow. Pass empty string '' for default UI or JSON for customization.
trackOfferDisplay(context)Tracks when the Appnomix offer CTA is displayed. Call with a context string describing where the offer was shown.

Troubleshooting

For error codes and troubleshooting, refer to the platform-specific documentation:


Wishing you a smooth integration! 🚀