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
| Method | Signature | Description |
|---|
present | present(flowId: string, context?: OnboardingContext): Promise<void> | Present an onboarding flow |
setDelegate | setDelegate(delegate: AppDNAOnboardingDelegate): void | Set 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
| Property | Type | Description |
|---|
source | string | undefined | Where the flow was triggered from |
campaign | string | undefined | Marketing campaign identifier |
referrer | string | undefined | Referral source |
userProperties | Record<string, unknown> | undefined | Custom user properties for targeting |
experimentOverrides | Record<string, string> | undefined | Override 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:
| Event | Payload | Triggered 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:
| Event | Triggered When |
|---|
onboarding_started | An onboarding flow is presented |
onboarding_step_viewed | A step is displayed to the user |
onboarding_step_completed | A step is completed |
onboarding_completed | The user completes the entire flow |
onboarding_dismissed | The 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.