Configuration for the In App survey in the React Native App.
Step 1: import Package
import { XeboSurveyManager, XeboSurveyModal } from 'react-native-my-survey-sdk';Step 2 : Getting your Credentials from the Xebo Platform.
All three values required for SDK configuartion are available directly in your Xebo Dashboard. No manual setup needed - just copy and paste.
API Key (api key)Log in to your Xebo account at app.xebo.ai
Go to the right first name of your Id then click icon and options are available go to My Account in the account details → API Keys
Copy your API Key
The API key authenticates all SDK requests. Keep it private — do not commit it to public repositories.
Collector ID (collector id)
In the Xebo Platform open your Survey those want to show in a app survey.
Navigate to Collectors.
Select the SDK collector.
Copy the Collector ID from the collector page.
A Collector is a distribution channel linked to a specific survey. The SDK uses this ID to automatically find and load the correct survey.
Zone (zone)
az1-api.xebo.ai “az1“ (Zone to use)
az2-api.xebo.ai “az2“
az4-api.xebo.ai “az4“
If you are unsure of your zone, contact your account manager or check the API base URL shown in your dashboard settings.
Step 3 : Configuration
Callconfigure()once insideuseEffectat your root ex:component. The SDK prefetches the survey immediately so the modal opens instantly when triggered.useEffect(() => { XeboSurveyManager.configure({ apiKey: 'YOUR_API_KEY', collectorId: 'YOUR_COLLECTOR_ID', zone: 'az2', environment: 'production', }); }, []);
Step 4 : Mounting the Survey Modal<XeboSurveyModal />must be mounted once at the root, outside all navigators, so it renders above everything:// App.tsx import { XeboSurveyManager, XeboSurveyModal } from 'react-native-my-survey-sdk'; export default function App() { useEffect(() => { XeboSurveyManager.configure({ /* config */ }); }, []); return ( <> <YourRootNavigator /> <XeboSurveyModal /> {/* Last child — renders on top */} </> ); }
Step 5 : Triggering a SurveyOn button press:
<TouchableOpacity onPress={() => XeboSurveyManager.fetchAndPresentSurvey()}> <Text>Share Feedback</Text> </TouchableOpacity>After an event (e.g. after a transaction):
const onOrderComplete = async () => { await submitOrder(); XeboSurveyManager.fetchAndPresentSurvey(); };On screen focus:
useFocusEffect(() => { XeboSurveyManager.fetchAndPresentSurvey(); });Dismiss programmatically:
XeboSurveyManager.dismissSurvey();
Step 6 : Theme CustomisationXeboSurveyManager.configureTheme({ primaryColor: '#0066CC', // Buttons, selected items backgroundColor: '#FFFFFF', // Modal background textColor: '#1F2937', // Question text cornerRadius: 14, // Modal and button radius (dp/pt) fontFamily: 'Roboto-Regular',// Custom font (must be linked) });Call
configureTheme()before or immediately afterconfigure().Property
Default
Description
primaryColor#4F46E5Accent color
backgroundColor#FFFFFFBackground
textColor#1F2937Text
cornerRadius12Border radius
fontFamilySystem font
Custom font
Step 7 : Event Systemimport { XeboSurveyManager, XEBO_EVENTS } from 'react-native-my-survey-sdk'; useEffect(() => { const onLoaded = () => console.log('Survey ready'); const onDismissed = () => console.log('Survey closed'); const onVisible = (v: boolean) => setIsSurveyOpen(v); XeboSurveyManager.on(XEBO_EVENTS.SURVEY_LOADED, onLoaded); XeboSurveyManager.on(XEBO_EVENTS.SURVEY_DISMISSED, onDismissed); XeboSurveyManager.on(XEBO_EVENTS.SURVEY_VISIBLE, onVisible); return () => { XeboSurveyManager.off(XEBO_EVENTS.SURVEY_LOADED, onLoaded); XeboSurveyManager.off(XEBO_EVENTS.SURVEY_DISMISSED, onDismissed); XeboSurveyManager.off(XEBO_EVENTS.SURVEY_VISIBLE, onVisible); }; }, []);Event
Payload
Fires when
SURVEY_LOADED—
Survey data fetched
QUESTION_CHANGED—
User moves to next question
SURVEY_VISIBLEbooleanModal opens (
true) or closes (false)SURVEY_DISMISSED—
Survey completed or dismissed
Step 8 : Hiding UI During Survey
Hide Bottom Tab Bar (React Navigation)
const [surveyVisible, setSurveyVisible] = useState(false);
useEffect(() => {
const onChange = (v: boolean) => setSurveyVisible(v);
XeboSurveyManager.on(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
return () => XeboSurveyManager.off(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
}, []);
// In Tab.Navigator:
screenOptions={{
tabBarStyle: surveyVisible ? { display: 'none' } : undefined,
}}
Add Scroll padding (prevent content hidden behind modal.
const SCREEN_HEIGHT = Dimensions.get('window').height;
<ScrollView
contentContainerStyle={{
paddingBottom: surveyVisible ? SCREEN_HEIGHT * 0.5 : 20,
}}
>
Step 9 : Offline Support
No extra configuration needed. The SDK:
Saves unanswered/failed responses to
AsyncStoragewhen offlineWatches network state via NetInfo
Automatically submits the queue when connectivity returns
Manual flush (optional):
await XeboSurveyManager.flushQueue();
Step 10 : TypeScript Reference
// Configuration
interface XeboConfig {
apiKey: string;
collectorId: string;
zone: string;
environment?: 'production' | 'uat';
}
// Theme
interface XeboThemeConfig {
primaryColor?: string;
backgroundColor?: string;
textColor?: string;
cornerRadius?: number;
fontFamily?: string;
}
// Manager
class XeboSurveyManager {
static configure(config: XeboConfig): void;
static configureTheme(config: XeboThemeConfig): void;
static fetchAndPresentSurvey(): Promise<void>;
static dismissSurvey(): void;
static flushQueue(): Promise<void>;
static on(event: string, listener: Function): void;
static off(event: string, listener: Function): void;
}
// Events
const XEBO_EVENTS = {
SURVEY_LOADED: 'survey_loaded',
QUESTION_CHANGED: 'question_changed',
SURVEY_VISIBLE: 'survey_visible', // payload: boolean
SURVEY_DISMISSED: 'survey_dismissed',
} as const;
Step 11 : Question Types
Type | UI | Description |
|---|---|---|
| Radio list | Pick one option |
| Checkbox list | Pick multiple options |
| Select picker | Pick one from a dropdown |
| Text input | Single open-ended response |
| Multiple inputs | Multiple labeled text fields |
| 0–10 scale | Net Promoter Score |
| NPS grid | NPS across multiple rows |
| Star/heart/emoji | Rating scale |
| Rating grid | Rating across multiple rows |
| Confirmation screen | Closing message |
NPS Default Color Zones:
Score | Zone | Color |
|---|---|---|
0–6 | Detractor |
|
7–8 | Passive |
|
9–10 | Promoter |
|
Step 12 : Custom Attributes (Edata)
Attaches user identity and custom data to every survey response submitted by the SDK. Call it once after the user logs in. The data is stored internally and sent automatically with each survey submission.
Basic usage — standard fields only:
XeboSurveyManager.setUser({
name: 'Sheetal',
email: 'sheetal@example.com',
phone: '+1234567890',
uniqueId: 'user_123',
country: 'US',
city: 'New York',
});With eData — custom fields your app defines:
XeboSurveyManager.setUser({
name: 'Sheetal',
email: 'sheetal@example.com',
phone: '+1234567890',
uniqueId: 'user_123',
country: 'US',
city: 'New York',
eData: {
role: 'admin',
organisation: 'Acme Corp',
business_unit: 'Engineering',
plan: 'enterprise',
account_type: 'paid',
// any key-value pairs your business needs
},
});Clear on logout:
XeboSurveyManager.clearUser();
Step 13 : Complete Example
App.tsx
import React, { useEffect } from 'react';
import { XeboSurveyManager, XeboSurveyModal } from 'react-native-my-survey-sdk';
export default function App() {
useEffect(() => {
XeboSurveyManager.configureTheme({ primaryColor: '#0066CC' });
XeboSurveyManager.configure({
apiKey: 'YOUR_API_KEY',
collectorId: 'YOUR_COLLECTOR_ID',
zone: 'YOUR_ZONE',
});
}, []);
return (
<>
<YourRootNavigator />
<XeboSurveyModal />
</>
);
}BottomTabNavigator.tsx
import React, { useEffect, useState } from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { XeboSurveyManager, XEBO_EVENTS } from 'react-native-my-survey-sdk';
const Tab = createBottomTabNavigator();
export const BottomTabNavigator = () => {
const [surveyVisible, setSurveyVisible] = useState(false);
useEffect(() => {
const onChange = (v: boolean) => setSurveyVisible(v);
XeboSurveyManager.on(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
return () => XeboSurveyManager.off(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
}, []);
return (
<Tab.Navigator
screenOptions={{ tabBarStyle: surveyVisible ? { display: 'none' } : undefined }}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
};FeedbackScreen.tsx
import React, { useEffect, useState } from 'react';
import { View, Text, TouchableOpacity, ScrollView, Dimensions, StyleSheet } from 'react-native';
import { XeboSurveyManager, XEBO_EVENTS } from 'react-native-my-survey-sdk';
const SCREEN_HEIGHT = Dimensions.get('window').height;
const FeedbackScreen = () => {
const [surveyVisible, setSurveyVisible] = useState(false);
useEffect(() => {
const onChange = (v: boolean) => setSurveyVisible(v);
XeboSurveyManager.on(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
return () => XeboSurveyManager.off(XEBO_EVENTS.SURVEY_VISIBLE, onChange);
}, []);
return (
<View style={styles.container}>
<ScrollView contentContainerStyle={{
paddingBottom: surveyVisible ? SCREEN_HEIGHT * 0.5 : 20,
}}>
<Text style={styles.title}>Help us improve</Text>
<TouchableOpacity
style={styles.button}
onPress={() => XeboSurveyManager.fetchAndPresentSurvey()}>
<Text style={styles.buttonText}>Share Feedback</Text>
</TouchableOpacity>
</ScrollView>
</View>
);
};
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, backgroundColor: '#fff' },
title: { fontSize: 20, fontWeight: '600', marginBottom: 24 },
button: { backgroundColor: '#0066CC', paddingVertical: 12, borderRadius: 8, alignItems: 'center' },
buttonText: { color: '#fff', fontSize: 15, fontWeight: '600' },
});
export default FeedbackScreen;Step :14 Troubleshooting
Survey modal does not appear
Confirm
configure()is called beforefetchAndPresentSurvey()Confirm
<XeboSurveyModal />is mounted at the app rootCheck API key, collector ID, and zone are correct
Check network connectivity
Missing module error on startup
npm install @react-native-async-storage/async-storage @react-native-community/netinfo react-native-modal react-native-reanimated
cd ios && pod installReanimated worklet error
Add 'react-native-reanimated/plugin' to plugins in babel.config.js, then:
npx react-native start --reset-cacheTab bar overlaps the survey
Follow Section 10 — listen to XEBO_EVENTS.SURVEY_VISIBLE and set tabBarStyle: { display: 'none' }.
Responses not submitting
Responses queue automatically offline and flush on reconnect. Call XeboSurveyManager.flushQueue() manually if needed.
For credentials (API key, collector ID, zone) or support, contact the Xebo team.