Skip to main content
The AppDNA onboarding module lets you present server-driven onboarding flows in your React Native app. Flows are configured in the AppDNA Console and rendered by the native layer — no client-side UI code required.

Present an Onboarding Flow

Use the top-level static method to present an onboarding flow by its ID:
import { AppDNA } from '@appdna/react-native-sdk';

await AppDNA.presentOnboarding("main_flow");
Onboarding flows are configured in the AppDNA Console under Onboarding > Flows. The SDK fetches the flow definition from the server and renders it using native UI components.

Onboarding Module

Access the onboarding module through the AppDNA.onboarding property for advanced usage:
const onboarding = AppDNA.onboarding;

Module Methods

MethodSignatureDescription
presentpresent(flowId: string, context?: OnboardingContext): Promise<void>Present an onboarding flow
setDelegatesetDelegate(delegate: AppDNAOnboardingDelegate): voidSet a delegate for lifecycle callbacks

Present with Context

Pass additional context to customize the onboarding flow:
await AppDNA.onboarding.present("main_flow", {
  source: "app_launch",
  campaign: "winter_promo",
  referrer: "friend_invite",
  userProperties: {
    tier: "free",
    signupDate: "2025-01-15",
  },
  experimentOverrides: {
    onboarding_variant: "b",
  },
});

OnboardingContext

PropertyTypeDescription
sourcestring | undefinedWhere the flow was triggered from
campaignstring | undefinedMarketing campaign identifier
referrerstring | undefinedReferral source
userPropertiesRecord<string, unknown> | undefinedCustom user properties for targeting
experimentOverridesRecord<string, string> | undefinedOverride experiment variant assignments

AppDNAOnboardingDelegate

Set a delegate to receive onboarding lifecycle callbacks:
interface AppDNAOnboardingDelegate {
  onOnboardingStarted(flowId: string): void;
  onOnboardingStepChanged(
    flowId: string,
    stepId: string,
    stepIndex: number,
    totalSteps: number
  ): void;
  onOnboardingCompleted(flowId: string, responses: Record<string, unknown>): void;
  onOnboardingDismissed(flowId: string, atStep: number): void;
}

Example Implementation

AppDNA.onboarding.setDelegate({
  onOnboardingStarted(flowId) {
    console.log(`Onboarding started: ${flowId}`);
  },

  onOnboardingStepChanged(flowId, stepId, stepIndex, totalSteps) {
    console.log(`Step ${stepIndex + 1}/${totalSteps}: ${stepId}`);
  },

  onOnboardingCompleted(flowId, responses) {
    console.log(`Onboarding completed: ${flowId}`);
    console.log("User responses:", responses);
    // Save responses or navigate to the main app
    navigateToHome();
  },

  onOnboardingDismissed(flowId, atStep) {
    console.log(`Onboarding dismissed at step ${atStep}: ${flowId}`);
    // Handle early exit
  },
});

NativeEventEmitter Events

The SDK emits the following onboarding events through React Native’s NativeEventEmitter:
EventPayloadTriggered When
onOnboardingStarted{ flowId: string }An onboarding flow begins
onOnboardingStepChanged{ flowId: string, stepId: string, stepIndex: number, totalSteps: number }The user moves to a new step
onOnboardingCompleted{ flowId: string, responses: Record<string, unknown> }The user completes the flow
onOnboardingDismissed{ flowId: string, atStep: number }The user dismisses the flow early
You do not need to subscribe to NativeEventEmitter events directly. The delegate interface handles event bridging for you. Use the native events only if you need custom low-level handling.

Auto-Tracked Events

The SDK automatically tracks the following onboarding-related events:
EventTriggered When
onboarding_startedAn onboarding flow is presented
onboarding_step_viewedA step is displayed to the user
onboarding_step_completedA step is completed
onboarding_completedThe user completes the entire flow
onboarding_dismissedThe user dismisses the flow early

Full Example

import { useEffect } from 'react';
import { AppDNA } from '@appdna/react-native-sdk';

function OnboardingScreen() {
  useEffect(() => {
    // Set delegate before presenting
    AppDNA.onboarding.setDelegate({
      onOnboardingStarted(flowId) {
        console.log("Started:", flowId);
      },
      onOnboardingStepChanged(flowId, stepId, stepIndex, totalSteps) {
        console.log(`Step ${stepIndex + 1}/${totalSteps}`);
        updateProgressBar(stepIndex, totalSteps);
      },
      onOnboardingCompleted(flowId, responses) {
        console.log("Completed with responses:", responses);
        saveOnboardingResponses(responses);
        navigateToHome();
      },
      onOnboardingDismissed(flowId, atStep) {
        console.log(`Dismissed at step ${atStep}`);
        navigateToHome();
      },
    });

    // Present the onboarding flow
    AppDNA.onboarding.present("main_flow", {
      source: "first_launch",
      userProperties: {
        platform: "react-native",
      },
    });
  }, []);

  return <LoadingScreen message="Loading onboarding..." />;
}
Always set the delegate before calling present() to ensure you receive the onOnboardingStarted callback.