### Install Flowboard SDK for Expo Source: https://docs.flow-board.co/quick-start Install the Flowboard React SDK for Expo and configure native dependencies. Ensure you have Expo installed in your project. ```bash npx expo install flowboard-react # Install and configure native dependencies npx --package flowboard-react flowboard-setup --yes ``` -------------------------------- ### Install Flowboard SDK for React Native Source: https://docs.flow-board.co/quick-start Install the Flowboard React SDK for React Native and configure peer dependencies. Ensure you have npm or yarn installed. ```bash npm install flowboard-react # Install and configure peer dependencies npx --package flowboard-react flowboard-setup --yes ``` -------------------------------- ### Install Amplitude and Adjust SDKs Source: https://docs.flow-board.co/custom-tracking Install the necessary packages for Amplitude and Adjust tracking in your React Native or Expo project. ```bash npm install @amplitude/analytics-react-native react-native-adjust ``` -------------------------------- ### Launch Tracked Flow in iOS (Swift) Source: https://docs.flow-board.co/custom-tracking This example demonstrates launching a Flowboard onboarding flow on iOS and sending custom tracking events for flow completion and step changes using `myTracking.track`. ```swift import FlowboardSwiftCore import FlowboardSwiftUIKit import UIKit func launchTrackedFlow(from host: UIViewController) { Task { do { try await Flowboard.launchOnboarding( from: host, options: .init( onOnboardEnd: { formData in print("Flow finished:", formData) myTracking.track( "flow_completed", properties: [ "plan": formData.string("plan") ?? "", "acceptedTerms": formData.bool("accept_terms") ?? false ] ) }, onStepChange: { stepId, pageStep, formData in print("User moved to step:", stepId ?? "", pageStep, formData) myTracking.track( "flow_step_viewed", properties: [ "stepId": stepId ?? "", "pageStep": pageStep, "plan": formData.string("plan") ?? "" ] ) } ) ) } catch { print("Failed to launch Flowboard:", error) } } } ``` -------------------------------- ### Launch Tracked Flow in Flutter Source: https://docs.flow-board.co/custom-tracking This example shows how to launch a Flowboard onboarding flow in Flutter and send custom tracking events for flow completion and step changes using `myTracking.track`. ```dart import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flowboard_flutter/flowboard_flutter.dart'; Future launchTrackedFlow(BuildContext context) async { await Flowboard.launchOnboarding( context, onOnboardEnd: (formData) { debugPrint('Flow finished: $formData'); myTracking.track('flow_completed', { 'plan': formData['plan'], 'acceptedTerms': formData['accept_terms'] == true, }); }, onStepChange: (stepId, pageStep, formData) { debugPrint('User moved to step: $stepId $pageStep $formData'); myTracking.track('flow_step_viewed', { 'stepId': stepId, 'pageStep': pageStep, 'plan': formData['plan'], }); }, ); } ``` -------------------------------- ### Install Flowboard SDK for Flutter Source: https://docs.flow-board.co/quick-start Add the flowboard_flutter package to your Flutter project's dependencies. Ensure you have Flutter installed and configured. ```bash flutter pub add flowboard_flutter ``` -------------------------------- ### Launch Tracked Flow in React Native / Expo Source: https://docs.flow-board.co/custom-tracking This example demonstrates how to launch a Flowboard onboarding flow and send custom tracking events for flow completion and step changes using `myTracking.track`. ```tsx import { Flowboard } from 'flowboard-react'; export async function launchTrackedFlow() { await Flowboard.launchOnboarding({ onOnboardEnd: (formData) => { console.log('Flow finished:', formData); myTracking.track('flow_completed', { plan: typeof formData.plan === 'string' ? formData.plan : undefined, acceptedTerms: Boolean(formData.accept_terms), }); }, onStepChange: (stepId, pageStep, formData) => { console.log('User moved to step:', stepId, pageStep, formData); myTracking.track('flow_step_viewed', { stepId, pageStep, plan: typeof formData.plan === 'string' ? formData.plan : undefined, }); }, }); } ``` -------------------------------- ### Handle Custom Actions in iOS Source: https://docs.flow-board.co/custom-screen Implement a workaround for custom screens in iOS by handling custom actions. This example shows how to trigger a native `PaywallViewController` from a Flowboard flow. ```swift import FlowboardSwiftCore import FlowboardSwiftUIKit import UIKit func startFlow(from host: UIViewController) { Task { do { try await Flowboard.launchOnboarding( from: host, options: .init( onCustomAction: { ctx in let actionName = ctx.action.payload.string("name") ?? "" guard actionName == "open_native_paywall" else { return .performDefault } let plan = ctx.values.string("plan") ?? "free" let controller = PaywallViewController(plan: plan) host.present(controller, animated: true) return .handled } ) ) } catch { print("Failed to launch Flowboard:", error) } } } ``` -------------------------------- ### Launch Flow with Step Change Callback (iOS) Source: https://docs.flow-board.co/retrieve-flow-data Utilize the `onStepChange` callback within the `Flowboard.launchOnboarding` options to track flow progression. This example shows how to send analytics data when a step changes. ```swift import FlowboardSwiftCore import FlowboardSwiftUIKit func startFlow() { Task { do { try await Flowboard.launchOnboarding( from: self, options: .init( onStepChange: { pageId, pageStep, formData in analytics.track( "flow_step_viewed", properties: [ "pageId": pageId ?? "", "pageStep": pageStep, "selectedPlan": formData.string("plan") ?? "" ] ) } ) ) } catch { print("Failed to launch Flowboard:", error) } } } ``` -------------------------------- ### Troubleshoot Expo Project Build Failures Source: https://docs.flow-board.co/quick-start If your Expo project fails after installing the SDK, clean the native project and reinstall dependencies. Ensure you rebuild the project afterwards. ```bash rm -rf ios/build rm -rf node_modules npm install npx expo prebuild --clean npx expo run:ios ``` -------------------------------- ### Custom Action Handler for iOS Source: https://docs.flow-board.co/custom-actions Implement a custom action handler for the 'open_checkout' action on iOS. This example shows how to present a checkout screen and handle the action result. ```swift import FlowboardSwiftCore import FlowboardSwiftUIKit import UIKit func startFlow(from host: UIViewController) { Task { do { try await Flowboard.launchOnboarding( from: host, options: .init( onCustomAction: { ctx in let actionName = ctx.action.payload.string("name") ?? "" guard actionName == "open_checkout" else { return .performDefault } let plan = ctx.action.payload.string("plan") ?? "free" billing.presentCheckout( plan: plan, customerEmail: ctx.values.string("email") ) return .handled } ) ) } catch { print("Failed to launch Flowboard:", error) } } } ``` -------------------------------- ### Launch Flow with onOnboardEnd Callback Source: https://docs.flow-board.co/retrieve-flow-data Use `onOnboardEnd` to get the final form data when the user completes the onboarding. Ensure your input IDs are stable as they become the keys in the `formData` object. ```tsx import { Flowboard } from 'flowboard-react'; export async function startFlow() { await Flowboard.launchOnboarding({ onOnboardEnd: (formData) => { const email = typeof formData.email === 'string' ? formData.email.trim() : ''; const selectedPlan = typeof formData.plan === 'string' ? formData.plan : 'free'; console.log('Flow completed', { email, selectedPlan, }); }, }); } ``` ```tsx import { Flowboard } from 'flowboard-react'; export async function startFlow() { await Flowboard.launchOnboarding({ onOnboardEnd: (formData) => { const email = typeof formData.email === 'string' ? formData.email.trim() : ''; const selectedPlan = typeof formData.plan === 'string' ? formData.plan : 'free'; console.log('Flow completed', { email, selectedPlan, }); }, }); } ``` ```dart import 'package:flutter/material.dart'; import 'package:flowboard_flutter/flowboard_flutter.dart'; Future startFlow(BuildContext context) async { await Flowboard.launchOnboarding( context, onOnboardEnd: (formData) { final email = (formData['email'] as String? ?? '').trim(); final selectedPlan = formData['plan'] as String? ?? 'free'; debugPrint('Flow completed: email=$email, plan=$selectedPlan'); }, ); } ``` ```swift import FlowboardSwiftCore import FlowboardSwiftUIKit func startFlow() { Task { do { try await Flowboard.launchOnboarding( from: self, options: .init( onOnboardEnd: { formData in let email = formData.string("email")? .trimmingCharacters(in: .whitespacesAndNewlines) ?? "" let selectedPlan = formData.string("plan") ?? "free" print("Flow completed: email=\(email), plan=\(selectedPlan)") } ) ) } catch { print("Failed to launch Flowboard:", error) } } } ``` -------------------------------- ### Launch Flow with Step Change and Custom Screens (React Native) Source: https://docs.flow-board.co/retrieve-flow-data Use `onStepChange` to track flow progress and `customScreenBuilder` to render custom UI components within the flow. This example demonstrates tracking step views and conditionally displaying a profile summary card. ```tsx await Flowboard.launchOnboarding({ onStepChange: (pageId, pageStep, formData) => { analytics.track('flow_step_viewed', { pageId, pageStep, selectedPlan: typeof formData.plan === 'string' ? formData.plan : undefined, }); }, customScreenBuilder: (ctx) => { if (ctx.screenData.id !== 'profile_summary') { return null; } return ( ); }, }); ``` -------------------------------- ### Launch Flow with Step Change and Custom Screens (Flutter) Source: https://docs.flow-board.co/retrieve-flow-data Implement `onStepChange` for analytics and `customScreenBuilder` for custom UI elements in Flutter flows. This example tracks step views and shows a `ProfileSummaryCard` when the 'profile_summary' screen is active. ```dart await Flowboard.launchOnboarding( context, onStepChange: (pageId, pageStep, formData) => { analytics.track('flow_step_viewed', { 'pageId': pageId, 'pageStep': pageStep, 'selectedPlan': formData['plan'], }); }, customScreenBuilder: (ctx) => { if (ctx.screenData['id'] != 'profile_summary') { return const SizedBox.shrink(); } return ProfileSummaryCard( name: ctx.formData['fullname'] as String? ?? '', email: ctx.formData['email'] as String? ?? '', onContinue: ctx.onNext, ); }, ); ``` -------------------------------- ### Launch Flowboard Onboarding Source: https://docs.flow-board.co/quick-start Use this to launch the default onboarding flow. The `onOnboardEnd` callback receives form data upon completion. ```tsx import { Button } from 'react-native'; import { Flowboard } from 'flowboard-react'; const startFlow = async () => { try { await Flowboard.launchOnboarding({ onOnboardEnd: (formData) => { console.log('Flow finished:', formData); }, }); } catch (error) { console.error('Failed to launch Flowboard:', error); } }; export function LaunchFlowButton() { return