Fetch and Show a Survey

Prev Next

Configuration for the In App survey in the React Native App.

     Step 1:  import Package

  1. 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)

    1. Log in to your Xebo account at app.xebo.ai

    2. 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

    3. 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)

    1. In the Xebo Platform open your Survey those want to show in a app survey.

    2. Navigate to Collectors.

    3. Select the SDK collector.

    4. 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)

    1. az1-api.xebo.ai    â€œaz1“ (Zone to use)

    2. az2-api.xebo.ai    â€œaz2“

    3. 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
    Call configure() once inside useEffect at 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 Survey

    On 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 Customisation

    XeboSurveyManager.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 after configure().

    Property

    Default

    Description

    primaryColor

    #4F46E5

    Accent color

    backgroundColor

    #FFFFFF

    Background

    textColor

    #1F2937

    Text

    cornerRadius

    12

    Border radius

    fontFamily

    System font

    Custom font


    Step 7 : Event System

    import { 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_VISIBLE

    boolean

    Modal 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:

  1. Saves unanswered/failed responses to AsyncStorage when offline

  2. Watches network state via NetInfo

  3. 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

singleChoice

Radio list

Pick one option

multipleChoice

Checkbox list

Pick multiple options

dropdown

Select picker

Pick one from a dropdown

singleTextBox

Text input

Single open-ended response

multipleTextBox

Multiple inputs

Multiple labeled text fields

nps

0–10 scale

Net Promoter Score

multiNps

NPS grid

NPS across multiple rows

rating

Star/heart/emoji

Rating scale

multiRating

Rating grid

Rating across multiple rows

thankYou

Confirmation screen

Closing message


NPS Default Color Zones:

Score

Zone

Color

0–6

Detractor

#F24236 (Red)

7–8

Passive

#FFC208 (Yellow)

9–10

Promoter

#2ECC70 (Green)

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 before fetchAndPresentSurvey()

  • Confirm <XeboSurveyModal /> is mounted at the app root

  • Check 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 install

Reanimated worklet error
Add 'react-native-reanimated/plugin' to plugins in babel.config.js, then:

npx react-native start --reset-cache

Tab 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.