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>
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:
-
Verify your credentials:
const client = new OnboardingStudioClient("your-project-id", {
appVersion: "1.0.0",
});Check that
projectIdis correct. -
Check customAudienceParams:
<OnboardingProvider
customAudienceParams={{
onboardingId: "your-onboarding-id", // Must match Rocapine dashboard
}}
/> -
Enable sandbox mode for debugging:
<OnboardingProvider isSandbox={true} /> -
Check network connectivity:
- Verify internet connection
- Check if API endpoint is accessible
- Look for CORS issues in dev tools
-
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:
-
Load fonts first:
import { useFonts } from 'expo-font';
const [fontsLoaded] = useFonts({
'CustomFont': require('./assets/fonts/CustomFont.ttf'),
});
if (!fontsLoaded) return null; // Important! -
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:
-
Check prop location:
// ✅ Correct
<ThemeProvider customTheme={{ colors: { primary: "#FF5733" } }}>
<YourApp />
</ThemeProvider>
// ❌ Wrong - theme must be on ThemeProvider
<OnboardingPage theme={{ colors: { primary: "#FF5733" } }} /> -
Verify deep merge syntax:
// ✅ Correct
customTheme={{
colors: {
text: { primary: "#000" }
}
}}
// ❌ Wrong - overwrites entire text object
customTheme={{
colors: {
text: "#000"
}
}} -
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:
-
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
}}
/> -
Check component props:
// ✅ Correct - implements full interface
const MyButton: React.FC<QuestionAnswerButtonProps> = (props) => { ... }
// ❌ Wrong - missing props
const MyButton = ({ answer }) => { ... } -
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:
-
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 />}
</>
); -
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} />;
}
Navigation not working in custom renderer
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:
-
Check ProgressBar placement:
// ✅ Correct - inside both providers
<OnboardingProvider>
<ThemeProvider>
<ProgressBar />
<YourApp />
</ThemeProvider>
</OnboardingProvider>
// ❌ Wrong - outside providers
<ProgressBar />
<OnboardingProvider>
<ThemeProvider>
<YourApp />
</ThemeProvider>
</OnboardingProvider> -
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:
-
Clear TypeScript cache:
rm -rf node_modules/.cache -
Reinstall dependencies:
npm install -
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:
-
Verify SDK installation:
npm install @rocapine/react-native-onboarding -
Check for version mismatch:
npm ls @rocapine/react-native-onboarding -
Clear Metro bundler cache:
npx expo start --clear
Performance Issues
Slow rendering or frame drops
Solutions:
-
Use native driver for animations:
Animated.timing(value, {
toValue: 1,
useNativeDriver: true, // Important!
}) -
Memoize custom components:
export const MyButton = React.memo<QuestionAnswerButtonProps>(({ ... }) => {
// Component logic
}); -
Optimize large lists: Use
FlatListinstead 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:
- Check the example app -
example/directory has working implementations - Enable sandbox mode - Get detailed error messages
- Check console logs - Look for warnings and errors
- Verify SDK version - Make sure you're using the latest version
Support Channels
- 📧 Email: support@rocapine.com
- 🐛 Issues: GitHub Issues
- 📚 Documentation: Rocapine Docs
When reporting issues, please include:
- SDK version
- React Native version
- Error messages
- Minimal reproduction code