Skip to main content

React Native SDK

The InHouse React Native SDK provides comprehensive tracking and analytics capabilities for your mobile applications, including user behavior tracking, deep linking support, install attribution, and device fingerprinting.

Installation

NPM Package

Install the SDK using npm:
npm install @tryinhouse/react-native-inhouse-sdk

Using yarn

yarn add @tryinhouse/react-native-inhouse-sdk

Platform Setup

iOS Setup

  1. Install CocoaPods dependencies:
cd ios && pod install
  1. Add Thumbmark Swift Package Dependency:
The SDK requires the Thumbmark Swift package for device fingerprinting and secure identification. Option A: Using Xcode (Recommended)
  1. Open your iOS project in Xcode (ios/YourApp.xcworkspace)
  2. Go to File → Add Package Dependencies…
  3. Enter the repository URL: https://github.com/thumbmarkjs/thumbmark-swift
  4. Select Up to Next Major Version and click Add Package
  5. Select the Thumbmark target and click Add Package
Option B: Using Package.swift (for SPM projects) Add the following to your Package.swift dependencies:
dependencies: [
    .package(url: "https://github.com/thumbmarkjs/thumbmark-swift", from: "1.1.0")
]
  1. Configure URL Schemes in ios/YourApp/Info.plist:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>your-app-identifier</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>myiosapp</string>
        </array>
    </dict>
</array>
  1. Add Associated Domains for universal links:
<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:your-shortlink-domain.tryinhouse.co</string>
</array>

Android Setup

The SDK uses React Native’s autolinking feature for automatic integration.
  1. Add Install Referrer Receiver to android/app/src/main/AndroidManifest.xml:
<application>
    <!-- Your existing application content -->

    <!-- Install Referrer Receiver -->
    <receiver
        android:name="co.tryinhouse.android.InstallReferrerReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name="com.android.vending.INSTALL_REFERRER" />
        </intent-filter>
    </receiver>
</application>
  1. Configure Deep Link Intent Filters in your main activity:
<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:theme="@style/AppTheme">

    <!-- Existing intent filters -->

    <!-- Custom Scheme Deep Links -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="myandroidapp"/>
    </intent-filter>

    <!-- App Links (Universal Links) -->
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="https" />
        <data android:host="your-shortlink-domain.tryinhouse.co" />
    </intent-filter>
</activity>

Quick Start

Basic Setup

Initialize the SDK in your app:
import TrackingSDK from "@tryinhouse/react-native-inhouse-sdk";

// Initialize the SDK
const initializeSDK = async () => {
  try {
    await TrackingSDK.initialize(
      "your-token-id", // Project ID from TryInHouse dashboard
      "your-project-token", // Project token from TryInHouse dashboard
      "your-shortlink-domain", // Your custom domain (e.g., 'myapp.tryinhouse.co')
      "https://api.tryinhouse.co", // Optional: API endpoint
      __DEV__ // Enable debug logging in development
    );

    console.log("SDK initialized successfully");
  } catch (error) {
    console.error("SDK initialization failed:", error);
  }
};

// Call during app startup
initializeSDK();

Handle App Lifecycle

import { AppState } from "react-native";

useEffect(() => {
  const handleAppStateChange = (nextAppState: string) => {
    if (nextAppState === "active") {
      TrackingSDK.onAppResume();
    }
  };

  const subscription = AppState.addEventListener(
    "change",
    handleAppStateChange
  );
  return () => subscription?.remove();
}, []);

Event Tracking

Track App Open

Track when users open your app:
// Basic app open tracking
const trackAppOpen = async () => {
  try {
    const result = await TrackingSDK.trackAppOpen();
    console.log("App open tracked:", result);
  } catch (error) {
    console.error("Failed to track app open:", error);
  }
};

// Track app open with specific shortlink
const trackAppOpenWithLink = async () => {
  try {
    const result = await TrackingSDK.trackAppOpen(
      "https://myapp.tryinhouse.co/abc123"
    );
    console.log("App open with shortlink tracked:", result);
  } catch (error) {
    console.error("Failed to track app open:", error);
  }
};

Track Session Start

Track user sessions:
// Basic session tracking
const trackSession = async () => {
  try {
    const result = await TrackingSDK.trackSessionStart();
    console.log("Session tracked:", result);
  } catch (error) {
    console.error("Failed to track session:", error);
  }
};

// Track session with shortlink context
const trackSessionWithLink = async () => {
  try {
    const result = await TrackingSDK.trackSessionStart(
      "https://myapp.tryinhouse.co/xyz789"
    );
    console.log("Session with shortlink tracked:", result);
  } catch (error) {
    console.error("Failed to track session:", error);
  }
};
Track when users interact with your short links:
// Track when user clicks on a short link
const trackShortLinkClick = async () => {
  try {
    const result = await TrackingSDK.trackShortLinkClick(
      "https://myapp.tryinhouse.co/campaign1", // Short link URL
      "myapp://product/123" // Optional: Deep link destination
    );
    console.log("Short link click tracked:", result);
  } catch (error) {
    console.error("Failed to track short link click:", error);
  }
};

Install Attribution

Install Referrer Tracking

Track install attribution and referrer data:
// Get stored install referrer
const getStoredReferrer = async () => {
  try {
    const referrer = await TrackingSDK.getInstallReferrer();
    console.log("Stored referrer:", referrer);
  } catch (error) {
    console.error("Error getting referrer:", error);
  }
};

// Fetch fresh install referrer data
const fetchFreshReferrer = async () => {
  try {
    const referrer = await TrackingSDK.fetchInstallReferrer();
    console.log("Fresh referrer:", referrer);
  } catch (error) {
    console.error("Error fetching referrer:", error);
  }
};

Reset First Install State

For testing install attribution:
// Reset first install state (use only for testing)
const resetFirstInstall = async () => {
  try {
    await TrackingSDK.resetFirstInstall();
    console.log("First install state reset");
  } catch (error) {
    console.error("Error resetting first install:", error);
  }
};

Real-time Event Callbacks

Listen to SDK events in real-time:
import { useEffect } from 'react';
import TrackingSDK, { TrackingSDKCallback } from "@tryinhouse/react-native-inhouse-sdk";

const useSDKCallbacks = () => {
  useEffect(() => {
    // Add callback listener
    const subscription = TrackingSDK.addCallbackListener((data: TrackingSDKCallback) => {
      console.log('SDK Event:', data.callbackType);
      console.log('Event Data:', data.data);

      switch (data.callbackType) {
        case 'session_start_shortlink':
          handleSessionWithShortlink(data.data);
          break;
        case 'app_open_shortlink':
          handleAppOpenFromShortlink(data.data);
          break;
        case 'app_install_from_shortlink':
          handleInstallFromShortlink(data.data);
          break;
        default:
          console.log('Unknown callback type:', data.callbackType);
      }
    });

    // Cleanup function
    return () => {
      TrackingSDK.removeCallbackListener(subscription);
    };
  }, []);
};

// Usage in component
const App = () => {
  useSDKCallbacks();

  return (
    // Your app content
  );
};
Handle incoming deep links from TryInHouse short links:
import { Linking } from "react-native";

const handleDeepLink = (url: string) => {
  console.log("Deep link received:", url);

  // Notify SDK about the new URL
  TrackingSDK.onNewURL(url);

  // Parse and handle the deep link
  if (url.includes("product/")) {
    const productId = url.split("product/")[1];
    // Navigate to product page
  }
};

useEffect(() => {
  // Handle initial URL (app opened via deep link)
  Linking.getInitialURL().then((url) => {
    if (url) {
      handleDeepLink(url);
    }
  });

  // Handle URLs while app is running
  const subscription = Linking.addEventListener("url", ({ url }) => {
    handleDeepLink(url);
  });

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

Device Fingerprinting

Thumbmark Integration

The SDK includes Thumbmark for device fingerprinting:
// Get device fingerprint
const getDeviceFingerprint = async () => {
  try {
    const fingerprint = await TrackingSDK.getFingerprint();
    console.log("Device fingerprint:", fingerprint);
  } catch (error) {
    console.error("Error getting fingerprint:", error);
  }
};

// Get fingerprint ID with specific algorithm
const getFingerprintId = async () => {
  try {
    const fingerprintId = await TrackingSDK.getFingerprintId("sha256");
    console.log("Fingerprint ID:", fingerprintId);
  } catch (error) {
    console.error("Error getting fingerprint ID:", error);
  }
};

Configuration Options

Debug Mode

Enable comprehensive logging during development:
await TrackingSDK.initialize(
  "token-id",
  "project-token",
  "domain",
  "https://api.tryinhouse.co",
  true // Enable debug logging
);

Dependency Versions

You can override dependency versions in your android/build.gradle:
ext {
    okhttpVersion = '4.12.0'
    gsonVersion = '2.10.1'
    installReferrerVersion = '2.2'
    coroutinesVersion = '1.7.3'
    coreKtxVersion = '1.12.0'
    appcompatVersion = '1.6.1'
}

TryInHouse Platform Configuration

Configure Well-Known Files

  1. Log in to TryInHouse Dashboard:
  2. Navigate to Project Settings:
    • Select your project from the dashboard
    • Go to SettingsLinkings
  3. Configure iOS Universal Links (apple-app-site-association):
{
  "applinks": {
    "details": [
      {
        "appIDs": ["TEAMID.com.yourcompany.yourapp"],
        "components": [
          {
            "/#": "*",
            "exclude": true,
            "comment": "Matches any URL with a fragment identifier"
          },
          {
            "/?*": "*",
            "comment": "Matches any URL with query parameters"
          },
          {
            "/": "*",
            "comment": "Matches the root URL and any path"
          }
        ]
      }
    ]
  },
  "webcredentials": {
    "apps": ["TEAMID.com.yourcompany.yourapp"]
  }
}
  1. Configure Android App Links (assetlinks.json):
[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.yourcompany.yourapp",
      "sha256_cert_fingerprints": ["YOUR_APP_SHA256_FINGERPRINT"]
    }
  }
]

API Reference

Core Methods

MethodDescriptionParametersReturns
initialize()Initialize the SDKprojectId, projectToken, domain, serverUrl?, debugMode?Promise<string>
onAppResume()Handle app resumeNonePromise<void>
onNewURL()Handle new URLurl: stringPromise<void>
trackAppOpen()Track app open eventshortLink?Promise<string>
trackSessionStart()Track session startshortLink?Promise<string>
trackShortLinkClick()Track link clickshortLink, deepLink?Promise<string>
getInstallReferrer()Get stored referrerNonePromise<string>
fetchInstallReferrer()Fetch fresh referrerNonePromise<string>
resetFirstInstall()Reset install stateNonePromise<void>

Device Fingerprinting Methods

MethodDescriptionParametersReturns
getFingerprint()Get device fingerprintNonePromise<string>
getFingerprintId()Get fingerprint IDalgorithm?Promise<string>

Event Listeners

MethodDescriptionParametersReturns
addCallbackListener()Add event listenercallback: (data) => voidEmitterSubscription
removeCallbackListener()Remove specific listenersubscriptionvoid
removeAllListeners()Remove all listenersNonevoid

TypeScript Types

interface TrackingSDKCallback {
  callbackType: string;
  data: string;
}

interface TrackingSDKInterface {
  initialize(
    tokenId: string,
    projectToken: string,
    shortLinkDomain: string,
    serverUrl?: string,
    enableDebugLogging?: boolean
  ): Promise<string>;

  onAppResume(): Promise<void>;
  onNewURL(url: string): Promise<void>;
  trackAppOpen(shortLink?: string): Promise<string>;
  trackSessionStart(shortLink?: string): Promise<string>;
  trackShortLinkClick(shortLink: string, deepLink?: string): Promise<string>;
  getInstallReferrer(): Promise<string>;
  fetchInstallReferrer(): Promise<string>;
  resetFirstInstall(): Promise<void>;
  getFingerprint(): Promise<string>;
  getFingerprintId(algorithm?: string): Promise<string>;
  addCallbackListener(
    callback: (data: TrackingSDKCallback) => void
  ): EmitterSubscription;
  removeCallbackListener(subscription: EmitterSubscription): void;
  removeAllListeners(): void;
}

Testing and Debugging

# Android testing
adb shell am start -W -a android.intent.action.VIEW -d "https://your-shortlink-domain.tryinhouse.co/test" com.yourcompany.yourapp

# iOS testing (use iOS Simulator)
xcrun simctl openurl booted "https://your-shortlink-domain.tryinhouse.co/test"

Example Test Scenarios

// Test deep link handling
const testDeepLink = async () => {
  const shortLink = "https://myapp.tryinhouse.co/test123";
  const deepLink = "myapp://home?tab=featured";

  await TrackingSDK.trackShortLinkClick(shortLink, deepLink);
};

// Test install referrer
const testInstallReferrer = async () => {
  const referrer = await TrackingSDK.fetchInstallReferrer();
  console.log("Test referrer:", referrer);
};

// Test device fingerprinting
const testFingerprinting = async () => {
  const fingerprint = await TrackingSDK.getFingerprint();
  const fingerprintId = await TrackingSDK.getFingerprintId();
  console.log("Fingerprint:", fingerprint);
  console.log("Fingerprint ID:", fingerprintId);
};

Troubleshooting

Common Issues

  • Check project ID and project token - Verify TryInHouse dashboard configuration - Check network connectivity - Enable debug logging to see detailed error messages
  • Verify InstallReferrerReceiver is added to AndroidManifest.xml - Test with Google Play Console’s internal testing - Check that app is installed from Play Store, not sideloaded - Use fetchInstallReferrer() to get fresh data

Best Practices

Event Tracking

  1. Initialize Early: Call initialize() as soon as possible in your app lifecycle
  2. Handle App Resume: Always call onAppResume() when the app becomes active
  3. Deep Link Handling: Use onNewURL() for all incoming deep links
  4. Error Handling: Wrap SDK calls in try-catch blocks

Performance

  1. Batch Operations: Avoid calling tracking methods in tight loops
  2. Background Processing: SDK handles background processing automatically
  3. Network Optimization: SDK batches events for optimal network usage

Next Steps

iOS SDK

Integrate with native iOS apps.

Android SDK

Integrate with native Android apps.

Deep Linking

Set up deep linking for seamless navigation.

Analytics

Understand your analytics data.
Need help with the React Native SDK? Check our API documentation or contact [email protected].