React Native SoluCX Widget
Paquete React Native para mostrar encuestas de satisfacción (NPS, CSAT, CES) de la plataforma SoluCX dentro de tu app.
Visión General
El widget carga la encuesta vía WebView y gestiona automáticamente las opciones de visualización (tipo, altura, frecuencia, muestreo y reglas de supresión). Solo necesitas informar los datos del cliente/transacción y el SDK se encarga del resto.
Modos de visualización: Bottom, Top, Modal e Inline.
Instalación
En proyectos React Native sin Expo (Bare React Native), debes instalar manualmente los módulos nativos después de la instalación del paquete. En proyectos con Expo Managed Workflow, la instalación de módulos nativos se realiza automáticamente.
Inicio Rápido
Existen dos formas de integrar el widget. Elige la que mejor se adapte a tu proyecto:
Integración por Función (recomendado)
Esta es la forma más flexible. Montas un SoluCXWidgetHost una vez en el root del app y disparas el widget desde cualquier lugar usando SoluCXWidget.create(...).show().
Paso 1: Monta el SoluCXWidgetHost en el root
El SoluCXWidgetHost es el contenedor que renderiza el widget. Debe montarse una única vez, en el componente raíz.
Paso 2: Dispara el widget desde cualquier pantalla
Llama a SoluCXWidget.create() cuando quieras mostrar la encuesta. Informa solo la clave, el tipo de visualización y los datos del cliente — el SDK busca las demás configuraciones (altura, frecuencia, muestreo, etc.) automáticamente del panel de la jornada.
Eso es todo. El SDK consulta la API, aplica las reglas de visualización configuradas en el panel y decide si el widget debe aparecer o no.
Paso 3 (opcional): Sobrescribe las opciones localmente
Si necesitas sobrescribir las configuraciones del panel para un caso específico, usa .setOptions(). Cuando se llama, el widget ignora la configuración remota y usa solo los valores proporcionados.
Resumen: setOptions() es opcional. Sin él, el widget busca todo de la API. Con él, controlas las configuraciones localmente.
Integración por Componente (alternativo)
Si prefieres controlar la visualización por el propio JSX, usa SoluCXWidgetView directamente. En este modo, no es necesario montar SoluCXWidgetHost — el componente es autosuficiente.
El componente se renderiza en la posición exacta donde se declara en JSX. Ideal para el modo inline.
Playground
Modos de Visualización
| Modo | Comportamiento |
|---|---|
bottom | Fijo en la parte inferior de la pantalla (por defecto) |
top | Fijo en la parte superior de la pantalla |
modal | Superposición centrada que bloquea la interacción con el fondo |
inline | Insertado en el flujo del layout, en la posición donde el componente es declarado |
Solo el modo inline respeta la posición en JSX. Los modos bottom, top y modal siempre aparecen en su posición fija correspondiente, independientemente de dónde se declare el componente.
Ejemplo Completo con Callbacks
Este ejemplo muestra todas las etapas del ciclo de vida del widget — de la preparación al cierre:
Cerrar el widget programáticamente
API
SoluCXWidget (clase principal)
Métodos de construcción (builder pattern)
| Método | Descripción |
|---|---|
SoluCXWidget.create(soluCXKey) | Crea una nueva instancia del widget |
.setType(type) | Define el tipo: 'bottom', 'top', 'modal', 'inline' |
.setData(data) | Define los datos del usuario/transacción |
.setOptions(options) | Define opciones del widget locales (opcional — si no se llama, busca de la API) |
.setCallbacks(callbacks) | Define callbacks de eventos |
.show() | Muestra el widget |
Métodos estáticos
| Método | Descripción |
|---|---|
SoluCXWidget.dismiss() | Cierra el widget programáticamente |
Métodos de instancia (gestión de logs)
Usan los datos del builder (instanceKey, journey, userId) para acceder a los logs de la combinación correcta.
| Método | Descripción |
|---|---|
.getWidgetLogs() | Retorna los logs del widget |
.overrideTimestamp(field, date) | Sobrescribe una fecha de evento (debug/pruebas) |
.clearWidgetLogs() | Limpia todos los logs |
Aislamiento de almacenamiento: Los logs están aislados por instanceKey:journey:userId. Un app con 2 widgets de jornadas diferentes tendrá datos independientes. El userId es opcional — cuando está presente, los logs son por usuario; cuando está ausente, son compartidos en el dispositivo.
WidgetData
Datos enviados para identificar al cliente y el contexto de la encuesta.
El campo customer_id es utilizado por el SDK para identificar al usuario y aplicar las reglas de visualización por persona. Si no se proporciona, el SDK busca document, email como fallback. Recomendamos siempre informar customer_id para que las reglas funcionen correctamente por usuario.
WidgetOptions
Configura las opciones de visualización del widget (tipo, altura, frecuencia, muestreo y reglas de supresión). Opcional — si setOptions() no se llama, el widget busca estas configuraciones automáticamente de la API (panel de configuración de la jornada).
| Propiedad | Tipo | Por defecto | Descripción |
|---|---|---|---|
enabled | boolean | true | Cuando false, bloquea inmediatamente sin validar otras reglas |
samplingPercentage | number | 100 | Porcentaje de usuarios que verán el widget (0-100). 100 = todos ven. 0 = nadie ve |
type | string | 'bottom' | Tipo de visualización: 'bottom', 'top', 'modal', 'inline'. Puede ser configurado remotamente por el panel de la jornada |
height | number | 600 | Altura fija del widget en píxeles. 0 = automático. Puede ser configurado remotamente por el panel de la jornada |
maxAttemptsAfterDismiss | number | 0 | Número máximo de visualizaciones por experiencia. 0 = sin límite. Se resetea cuando el ID de la experiencia cambia |
waitDaysAfterWidgetDisplayAttempt | number | 0 | Días a esperar después de un intento de visualización bloqueado |
waitDaysAfterWidgetFirstAccess | number | 0 | Días a esperar después del primer acceso del usuario a la jornada |
waitDaysAfterWidgetDisplay | number | 0 | Días a esperar después de cualquier visualización del widget |
waitDaysAfterWidgetDismiss | number | 0 | Días a esperar después de que el usuario cierre el widget |
waitDaysAfterWidgetSubmit | number | 0 | Días a esperar después de envío completo de la encuesta |
waitDaysAfterWidgetPartialSubmit | number | 0 | Días a esperar después de envío parcial de la encuesta |
Consejo: Un valor de 0 en los campos de días = sin restricción (el campo no bloquea). Las configuraciones pueden gestionarse remotamente por el panel de la jornada — así no necesitas actualizar el app para cambiar las reglas.
Importante sobre Cuarentena: El control de cuarentena del widget se basa en las cookies del navegador del cliente. Esto significa que la cuarentena no está 100% garantizada, ya que el usuario puede borrar las cookies, usar diferentes navegadores, diferentes dispositivos o modo de navegación incógnito/privado. Para escenarios que requieren un control estricto de cuarentena, recomendamos implementar validaciones adicionales en el lado del servidor.
WidgetCallbacks
Funciones llamadas en cada etapa del ciclo de vida del widget. Todas son opcionales.
Ciclo de vida
Al llamar .show(), el SDK ejecuta los siguientes pasos:
- Verifica las opciones locales (enabled, muestreo, intentos, intervalos)
- Si bloqueado: llama a
onBlockedcon el motivo y el widget no aparece - Si liberado: solicita la URL de la encuesta a la API SoluCX (preflight)
- Llama a
onPreOpen→ muestra el widget → llama aonOpened - Durante la encuesta, el usuario interactúa con el formulario
- Cuando el usuario responde la nota principal (NPS/CSAT/CES): llama a
onPartialCompleted - Cuando el usuario completa toda la encuesta: llama a
onCompleted - Al cerrar (por el usuario o automáticamente): llama a
onClosed - Si ocurre un error en cualquier etapa: llama a
onError
La validación de las reglas de visualización se realiza localmente, antes de llamar a la API, para reducir la carga en el servidor.
Descripción de los callbacks
| Callback | Parámetro | Cuándo se llama |
|---|---|---|
onPreOpen | userId: string | Inmediatamente antes de que el widget sea mostrado, después de pasar la validación de reglas de visualización |
onOpened | userId: string | Cuando el widget se muestra en pantalla |
onBlocked | reason: BlockReason | Cuando las reglas de visualización impiden que el widget se muestre. Ver BlockReason |
onClosed | - | Cuando el widget se cierra, ya sea por el usuario o automáticamente |
onCompleted | userId: string | Cuando el usuario completa toda la encuesta (todas las etapas) |
onPartialCompleted | userId: string | Cuando el usuario responde la nota principal (NPS/CSAT/CES) |
onError | message: string | Cuando ocurre un error en la encuesta (encuesta expirada, ya evaluada, fallo de red) |
onPageChanged | page: string | Cuando el usuario navega entre páginas (Flex Survey) |
onQuestionAnswered | - | Cuando el usuario responde una pregunta (Flex Survey) |
onResize | height: string | Cuando la altura del widget cambia |
BlockReason
Motivos por los cuales las reglas de visualización impiden que el widget se muestre. Estos bloqueos son locales (en el dispositivo) y no representan errores de la API.
| Razón | Descripción |
|---|---|
BLOCKED_BY_DISABLED | Widget deshabilitado (enabled: false) |
BLOCKED_BY_SAMPLING | Usuario no fue seleccionado por el muestreo (samplingPercentage) |
BLOCKED_BY_TRANSACTION_ALREADY_ANSWERED | Transacción ya fue respondida anteriormente |
BLOCKED_BY_MAX_ATTEMPTS | Número máximo de intentos alcanzado para esta experiencia |
BLOCKED_BY_WIDGET_DISPLAY_ATTEMPT_INTERVAL | Dentro del intervalo después de intento de visualización |
BLOCKED_BY_WIDGET_FIRST_ACCESS_INTERVAL | Dentro del intervalo después del primer acceso a la jornada |
BLOCKED_BY_WIDGET_DISPLAY_INTERVAL | Dentro del intervalo después de visualización |
BLOCKED_BY_WIDGET_DISMISS_INTERVAL | Dentro del intervalo después de cierre |
BLOCKED_BY_WIDGET_SUBMIT_INTERVAL | Dentro del intervalo después de envío completo |
BLOCKED_BY_WIDGET_PARTIAL_SUBMIT_INTERVAL | Dentro del intervalo después de envío parcial |
Múltiples Widgets
Cada combinación de instanceKey + journey + userId opera con logs independientes:
Solución de Problemas
El widget no aparece
- Verifica que la clave SoluCX (
soluCXKey) sea válida - Verifica la conectividad a internet
- Usa el callback
onBlockedpara verificar si las reglas de visualización están impidiendo la visualización - Usa el callback
onErrorpara verificar si hay errores en la encuesta
Los callbacks no se llaman
- Confirma que el objeto
callbacksse está pasando vía.setCallbacks()o como prop delSoluCXWidgetView - Verifica la consola para mensajes de error del WebView
Layout roto
- Define una altura fija vía
setOptions({ height: 600 })si el redimensionamiento automático no funciona bien en tu layout - Para el modo
inline, asegúrate de que el componente padre tiene espacio suficiente
Compatibilidad
| Versión | React Native | Expo | iOS | Android |
|---|---|---|---|---|
| 2.x | 0.70+ | 50+ | 11+ | API 21+ |
Licencia
Este paquete es propiedad de SoluCX. El uso está restringido a clientes licenciados de la plataforma SoluCX.