Skip to main content

Troubleshooting

Common issues and solutions when using the Rocapine Onboarding Studio SDK.

Installation Issues

Cannot find module 'expo-router'

Error:

Module not found: Error: Can't resolve 'expo-router'

Solution: Install the required peer dependency:

npx expo install expo-router

The SDK requires expo-router for navigation patterns.


Missing peer dependencies for specific screen types

Error:

Error: @react-native-picker/picker is required for Picker screens

Solution: Install the optional dependency for the screen type you're using:

For Picker screens:

npx expo install @react-native-picker/picker

For Ratings screens:

npx expo install expo-store-review

For Commitment screens (signature only):

npx expo install @shopify/react-native-skia

See Getting Started → Optional Dependencies for the complete list.


Runtime Errors

useSuspenseQuery requires a Suspense boundary

Error:

Error: useSuspenseQuery must be used within a Suspense boundary

Solution: Wrap your onboarding screen with a Suspense boundary:

import { Suspense } from "react";

<Suspense fallback={<LoadingScreen />}>
<OnboardingScreen />
</Suspense>
tip

Expo Router handles Suspense automatically in most cases. This error typically occurs with custom routing setups.


Steps not loading

Symptoms:

  • Blank screen
  • Infinite loading
  • No data returned

Troubleshooting steps:

  1. Verify your credentials:

    const client = new OnboardingStudioClient("your-project-id", {
    appVersion: "1.0.0",
    });

    Check that projectId is correct.

  2. Check customAudienceParams:

    <OnboardingProvider
    customAudienceParams={{
    onboardingId: "your-onboarding-id", // Must match Rocapine dashboard
    }}
    />
  3. Enable sandbox mode for debugging:

    <OnboardingProvider isSandbox={true} />
  4. Check network connectivity:

    • Verify internet connection
    • Check if API endpoint is accessible
    • Look for CORS issues in dev tools
  5. Check console logs: Sandbox mode provides detailed error messages.


Custom fonts not working

Error:

Text strings must be rendered within a <Text> component.

or fonts don't appear as expected.

Solution:

  1. Load fonts first:

    import { useFonts } from 'expo-font';

    const [fontsLoaded] = useFonts({
    'CustomFont': require('./assets/fonts/CustomFont.ttf'),
    });

    if (!fontsLoaded) return null; // Important!
  2. Then configure theme:

    <ThemeProvider
    customTheme={{
    typography: {
    fontFamily: { title: "CustomFont" }
    }
    }}
    >
    <YourApp />
    </ThemeProvider>

The SDK does not load fonts - you must load them using expo-font first.


Theme Issues

Theme tokens not applying

Symptoms:

  • Colors don't change
  • Typography stays default

Troubleshooting:

  1. Check prop location:

    // ✅ Correct
    <ThemeProvider customTheme={{ colors: { primary: "#FF5733" } }}>
    <YourApp />
    </ThemeProvider>

    // ❌ Wrong - theme must be on ThemeProvider
    <OnboardingPage theme={{ colors: { primary: "#FF5733" } }} />
  2. Verify deep merge syntax:

    // ✅ Correct
    customTheme={{
    colors: {
    text: { primary: "#000" }
    }
    }}

    // ❌ Wrong - overwrites entire text object
    customTheme={{
    colors: {
    text: "#000"
    }
    }}
  3. Check mode-specific themes:

    // If you want different colors per mode:
    <ThemeProvider
    customLightTheme={{ colors: { primary: "#007AFF" } }}
    customDarkTheme={{ colors: { primary: "#0A84FF" } }}
    >
    <YourApp />
    </ThemeProvider>

Text styles not working

Solution:

Use getTextStyle() instead of directly accessing text styles:

// ✅ Correct
import { getTextStyle } from "@rocapine/react-native-onboarding-ui";

const textStyle = getTextStyle(theme, "heading1");

// ❌ Wrong
const textStyle = theme.textStyles.heading1; // textStyles doesn't exist on theme

Custom Component Issues

Custom component not rendering

Troubleshooting:

  1. Verify prop name:

    // ✅ Correct - passed to OnboardingPage
    <OnboardingPage
    step={step}
    onContinue={handleContinue}
    customComponents={{
    QuestionAnswerButton: MyButton // Exact name
    }}
    />

    // ❌ Wrong
    <OnboardingPage
    step={step}
    onContinue={handleContinue}
    customComponents={{
    questionAnswerButton: MyButton // Wrong casing
    }}
    />
  2. Check component props:

    // ✅ Correct - implements full interface
    const MyButton: React.FC<QuestionAnswerButtonProps> = (props) => { ... }

    // ❌ Wrong - missing props
    const MyButton = ({ answer }) => { ... }
  3. Verify component priority:

    // QuestionAnswersList overrides QuestionAnswerButton
    <OnboardingPage
    step={step}
    onContinue={handleContinue}
    customComponents={{
    QuestionAnswersList: MyList, // This wins
    QuestionAnswerButton: MyButton, // Ignored
    }}
    />

Custom Renderer Issues

Custom renderer not being called

Troubleshooting:

  1. Check condition placement:

    // ✅ Correct - before OnboardingPage
    export default function OnboardingScreen() {
    const { step } = useOnboardingQuestions({ stepNumber });

    if (step.id === "custom") {
    return <CustomRenderer step={step} onContinue={onContinue} />;
    }

    return <OnboardingPage step={step} onContinue={onContinue} />;
    }

    // ❌ Wrong - after OnboardingPage (unreachable)
    return (
    <>
    <OnboardingPage step={step} onContinue={onContinue} />
    {step.id === "custom" && <CustomRenderer />}
    </>
    );
  2. Verify condition matching:

    // Debug by logging
    console.log("Step ID:", step.id);
    console.log("Step Type:", step.type);

    if (step.id === "welcome") { // Check this matches
    return <CustomRenderer step={step} onContinue={onContinue} />;
    }

Solution:

Always call onContinue when done:

// ✅ Correct
<Button onPress={() => onContinue(selectedValues)} />

// ❌ Wrong - navigation breaks
<Button onPress={() => console.log("Done")} />

Progress Bar Issues

Progress bar not showing

Troubleshooting:

  1. Check ProgressBar placement:

    // ✅ Correct - inside both providers
    <OnboardingProvider>
    <ThemeProvider>
    <ProgressBar />
    <YourApp />
    </ThemeProvider>
    </OnboardingProvider>

    // ❌ Wrong - outside providers
    <ProgressBar />
    <OnboardingProvider>
    <ThemeProvider>
    <YourApp />
    </ThemeProvider>
    </OnboardingProvider>
  2. Check displayProgressHeader flag:

    // Progress bar respects this field
    {
    displayProgressHeader: true, // Progress bar shows
    }

Progress not updating

Solution:

Ensure you're using useOnboardingQuestions which automatically updates progress:

// ✅ Correct - updates progress context
const { step } = useOnboardingQuestions({ stepNumber });

// ❌ Wrong - no progress update
const step = await client.getSteps();

Build and Type Errors

TypeScript errors after SDK update

Solution:

  1. Clear TypeScript cache:

    rm -rf node_modules/.cache
  2. Reinstall dependencies:

    npm install
  3. Restart TypeScript server in your editor


Build fails with asset errors

Symptoms:

Error: Asset not found: assets/...

Solution:

The SDK handles assets automatically. If you see this error:

  1. Verify SDK installation:

    npm install @rocapine/react-native-onboarding
  2. Check for version mismatch:

    npm ls @rocapine/react-native-onboarding
  3. Clear Metro bundler cache:

    npx expo start --clear

Performance Issues

Slow rendering or frame drops

Solutions:

  1. Use native driver for animations:

    Animated.timing(value, {
    toValue: 1,
    useNativeDriver: true, // Important!
    })
  2. Memoize custom components:

    export const MyButton = React.memo<QuestionAnswerButtonProps>(({ ... }) => {
    // Component logic
    });
  3. Optimize large lists: Use FlatList instead of mapping in custom list components:

    <FlatList
    data={answers}
    renderItem={({ item }) => <AnswerButton answer={item} />}
    keyExtractor={(item) => item.value}
    />

Cache Issues

Stale data showing

Solution:

Clear the AsyncStorage cache:

import { useQueryClient } from "@tanstack/react-query";

const queryClient = useQueryClient();

// Invalidate cache
queryClient.invalidateQueries({ queryKey: ["onboardingSteps"] });

Getting Help

If you're still experiencing issues:

  1. Check the example app - example/ directory has working implementations
  2. Enable sandbox mode - Get detailed error messages
  3. Check console logs - Look for warnings and errors
  4. Verify SDK version - Make sure you're using the latest version

Support Channels

When reporting issues, please include:

  • SDK version
  • React Native version
  • Error messages
  • Minimal reproduction code