React Native SoluCX Widget

A modular React Native widget for feedback and satisfaction surveys, developed by SoluCX following Clean Code principles and scalable architecture.

🛠️ Technologies

📋 Overview

The SoluCX Widget allows you to integrate satisfaction surveys directly into React Native/Expo applications simply and flexibly. Designed for companies that need to collect real-time feedback through different presentation modes.

🎯 Main Features

  • 4 Rendering Modes: Bottom, Top, Modal, and Inline
  • Automatic Persistence: Smart frequency control
  • WebView Communication: Seamless integration with SoluCX platform
  • TypeScript: Fully typed for better developer experience
  • High Performance: Optimized loading and local cache

🚀 Installation

npm
pnpm
bun
yarn
npx expo install @solucx/react-native-solucx-widget

🎛️ Basic Usage

🎛️ Basic Usage
app.tsx
import { SoluCXWidget } from '@solucx/react-native-solucx-widget';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <SoluCXWidget
        soluCXKey=""
        type="inline"
        data={{
          journey: "",
          name: "Cliente",
          email: '[email protected]',
          store_id: '1',
          employee_id: '1',
          amount: 10,
          param_REGIAO: 'SUDESTE'
        }}
        options={{}}
      />
    </View>
  );
}
package.json
{
  "dependencies": {
    "@solucx/react-native-solucx-widget": "^0.1.5"
  }
}

Playground

📱 Rendering Modes

Bottom (Default)

Widget fixed at the bottom of the screen, ideal for non-intrusive feedback.

<SoluCXWidget type="bottom" {...props} />

Top

Widget fixed at the top of the screen, perfect for important notifications.

<SoluCXWidget type="top" {...props} />

Centered overlay that blocks interaction with the background.

<SoluCXWidget type="modal" {...props} />

Inline

Integrated into the normal layout flow, respecting its position in the code.

<SoluCXWidget type="inline" {...props} />

🔧 Full API

Props

PropertyTypeRequiredDescription
soluCXKeystringSoluCX authentication key
typeWidgetTypeRendering mode
dataWidgetDataCustomer/transaction data
optionsWidgetOptionsWidget settings
callbacksWidgetCallbacksCallbacks for journey tracking

WidgetData

interface WidgetData {
  // Identifiers
  transaction_id?: string;
  customer_id?: string;
  
  // Customer data
  name?: string;
  email?: string;
  phone?: string;
  birth_date?: string;     // Format: YYYY-MM-DD
  document?: string;
  
  // Transaction context
  store_id?: string;
  store_name?: string;
  employee_id?: string;
  employee_name?: string;
  amount?: number;
  score?: number;
  journey?: string;        // Journey/flow name
  
  // Custom parameters (prefix param_)
  param_REGION?: string;
  [key: string]: string | number | undefined;
}

WidgetOptions

interface WidgetOptions {
  height?: number;         // Height
  retry?: {
    attempts?: number;     // Attempts (default: 3)
    interval?: number;     // Interval in ms (default: 1000)
  };
  waitDelayAfterRating?: number; // Delay after rating
}

WidgetType

type WidgetType = "bottom" | "top" | "inline" | "modal";

WidgetCallbacks

interface WidgetCallbacks {
    onOpened?: (userId: string) => void;
    onClosed?: () => void;
    onError?: (message: string) => void;
    onPageChanged?: (page: string) => void;
    onQuestionAnswered?: () => void;
    onCompleted?: (userId: string) => void;
    onPartialCompleted?: (userId: string) => void;
    onResize?: (height: string) => void;
}
CallbackParameterDescription
onOpeneduserId: stringCalled when the widget is opened
onClosed-Called when the widget is closed
onErrormessage: stringCalled when a loading error occurs
onPageChangedpage: stringCalled when the user navigates between survey pages
onQuestionAnswered-Called when the user answers a question
onCompleteduserId: stringCalled when the survey is completed
onPartialCompleteduserId: stringCalled when the survey is partially completed
onResizeheight: stringCalled when the widget is resized

Example with Callbacks

import { SoluCXWidget } from '@solucx/react-native-solucx-widget';

export default function App() {
  return (
    <SoluCXWidget
      soluCXKey="YOUR_KEY"
      type="modal"
      data={{
        journey: "purchase",
        name: "Customer",
        email: "[email protected]",
        store_id: "1",
      }}
      options={{}}
      callbacks={{
        onOpened: (userId) => {
          console.log('Widget opened for:', userId);
        },
        onCompleted: (userId) => {
          console.log('Survey completed by:', userId);
        },
        onPageChanged: (page) => {
          console.log('Page changed:', page);
        },
        onQuestionAnswered: () => {
          console.log('Question answered');
        },
        onClosed: () => {
          console.log('Widget closed');
        },
        onError: (message) => {
          console.error('Widget error:', message);
        },
      }}
    />
  );
}

🔄 Event System

The widget automatically processes the following survey events:

  • FORM_OPENED - Widget opened
  • FORM_CLOSE - User closed the widget
  • FORM_COMPLETED - Survey completed
  • FORM_PARTIALCOMPLETED - Partially completed
  • FORM_RESIZE - Widget resized
  • FORM_ERROR - Loading error
  • FORM_PAGECHANGED - Survey page changed
  • QUESTION_ANSWERED - Question answered

💾 Smart Persistence

The widget automatically controls:

  • Attempt history: Prevents widget spam
  • Last rating: Date of last interaction
  • Frequency control: Respects display settings
  • Local storage: Data persists between sessions

⚙️ Multiple Widgets

const widgets = ['bottom', 'top'] as WidgetType[];

return (
  <>
    {widgets.map((type) => (
      <SoluCXWidget
        key={type}
        soluCXKey={key}
        type={type}
        data={data}
        options={options}
      />
    ))}
  </>
);

🚨 Important Considerations

Positioning

⚠️ Critical Behavior: The position in JSX does not determine where top, bottom, and modal widgets appear:

// ❌ "bottom" widget always appears at the bottom, regardless of position
<Text>Content before</Text>
<SoluCXWidget type="bottom" {...props} />
<Text>Content after</Text>

// ✅ Only "inline" respects its position in the code
<Text>Content before</Text>
<SoluCXWidget type="inline" {...props} />
<Text>Content after</Text>

🔍 Troubleshooting

Widget does not appear

// Essential checks:
// ✅ Valid SoluCX key?
// ✅ Internet connectivity?
// ✅ WebView logs in console?
// ✅ Required data filled?

Events not working

// Communication debug:
const handleMessage = (message: string) => {
  console.log('Widget event:', message);
};

// Check if JavaScript was injected correctly

Broken layout

// Adjust dimensions for the device:
const { height } = Dimensions.get('window');

const options = {
  height: Math.min(height * 0.6, 400)
};

📚 Compatibility

VersionReact NativeExpoiOSAndroid
1.0.x0.70+50+11+API 21+

📄 License

This package is proprietary to SoluCX. Use is restricted to licensed SoluCX platform customers.