React Native SoluCX Widget
Pacote React Native para exibir pesquisas de satisfação (NPS, CSAT, CES) da plataforma SoluCX dentro do seu app.
Visão Geral
O widget carrega a pesquisa via WebView e gerencia automaticamente as opções de exibição (tipo, altura, frequência, amostragem e regras de supressão). Você só precisa informar os dados do cliente/transação e o SDK cuida do resto.
Modos de exibição: Bottom, Top, Modal e Inline.
Instalação
Em projetos React Native sem Expo (Bare React Native), você deve instalar manualmente os módulos nativos após a instalação do pacote. Em projetos com Expo Managed Workflow, a instalação dos módulos nativos é feita automaticamente.
Início Rápido
Existem duas formas de integrar o widget. Escolha a que melhor se encaixa no seu projeto:
Integração por Função (recomendado)
Essa é a forma mais flexível. Você monta um SoluCXWidgetHost uma vez no root do app e dispara o widget de qualquer lugar usando SoluCXWidget.create(...).show().
Passo 1: Monte o SoluCXWidgetHost no root
O SoluCXWidgetHost é o contêiner que renderiza o widget. Ele deve ser montado uma única vez, no componente raiz.
Passo 2: Dispare o widget em qualquer tela
Chame SoluCXWidget.create() quando quiser exibir a pesquisa. Informe apenas a chave, o tipo de exibição e os dados do cliente — o SDK busca as demais configurações (altura, frequência, amostragem, etc.) automaticamente do painel da jornada.
Só isso. O SDK consulta a API, aplica as regras de exibição configuradas no painel e decide se o widget deve aparecer ou não.
Passo 3 (opcional): Sobrescreva as opções localmente
Se você precisar sobrescrever as configurações do painel para um caso específico, use .setOptions(). Quando chamado, o widget ignora a configuração remota e usa apenas os valores fornecidos.
Resumo: setOptions() é opcional. Sem ele, o widget busca tudo da API. Com ele, você controla localmente.
Integração por Componente (alternativo)
Se preferir controlar a exibição pelo próprio JSX, use SoluCXWidgetView diretamente. Nesse modo, não é necessário montar SoluCXWidgetHost — o componente é autossuficiente.
O componente é renderizado na posição exata onde é declarado no JSX. Ideal para o modo inline.
Playground
Modos de Exibição
| Modo | Comportamento |
|---|---|
bottom | Fixo na parte inferior da tela (padrão) |
top | Fixo no topo da tela |
modal | Sobreposição centralizada que bloqueia a interação com o fundo |
inline | Inserido no fluxo do layout, na posição onde o componente é declarado |
Apenas o modo inline respeita a posição no JSX. Os modos bottom, top e modal sempre aparecem na posição fixa correspondente, independente de onde o componente é declarado.
Exemplo Completo com Callbacks
Este exemplo mostra todas as etapas do ciclo de vida do widget — da preparação ao fechamento:
Fechar o widget programaticamente
API
SoluCXWidget (classe principal)
Métodos de construção (builder pattern)
| Método | Descrição |
|---|---|
SoluCXWidget.create(soluCXKey) | Cria uma nova instância do widget |
.setType(type) | Define o tipo: 'bottom', 'top', 'modal', 'inline' |
.setData(data) | Define os dados do usuário/transação |
.setOptions(options) | Define opções do widget locais (opcional — se não chamar, busca da API) |
.setCallbacks(callbacks) | Define callbacks de eventos |
.show() | Exibe o widget |
Métodos estáticos
| Método | Descrição |
|---|---|
SoluCXWidget.dismiss() | Fecha o widget programaticamente |
Métodos de instância (gerenciamento de logs)
Usam os dados do builder (instanceKey, journey, userId) para acessar os logs da combinação correta.
| Método | Descrição |
|---|---|
.getWidgetLogs() | Retorna os logs do widget |
.overrideTimestamp(field, date) | Sobrescreve uma data de evento (debug/teste) |
.clearWidgetLogs() | Limpa todos os logs |
Isolamento de armazenamento: Os logs são isolados por instanceKey:journey:userId. Um app com 2 widgets de jornadas diferentes terá dados independentes. O userId é opcional — quando presente, os logs são por usuário; quando ausente, são compartilhados no dispositivo.
WidgetData
Dados enviados para identificar o cliente e o contexto da pesquisa.
O campo customer_id é usado pelo SDK para identificar o usuário e aplicar as regras de exibição por pessoa. Se não for informado, o SDK usa document, email como fallback. Recomendamos sempre informar customer_id para que as regras funcionem corretamente por usuário.
WidgetOptions
Configura as opções de exibição do widget (tipo, altura, frequência, amostragem e regras de supressão). Opcional — se setOptions() não for chamado, o widget busca essas configurações automaticamente da API (painel de configuração da jornada).
| Propriedade | Tipo | Padrão | Descrição |
|---|---|---|---|
enabled | boolean | true | Quando false, bloqueia imediatamente sem validar outras regras |
samplingPercentage | number | 100 | Porcentagem de usuários que verão o widget (0-100). 100 = todos veem. 0 = ninguém vê |
type | string | 'bottom' | Tipo de exibição: 'bottom', 'top', 'modal', 'inline'. Pode ser configurado remotamente pelo painel da jornada |
height | number | 600 | Altura fixa do widget em pixels. 0 = automático. Pode ser configurado remotamente pelo painel da jornada |
maxAttemptsAfterDismiss | number | 0 | Número máximo de exibições por experiência. 0 = sem limite. Reseta quando o ID da experiência muda |
waitDaysAfterWidgetDisplayAttempt | number | 0 | Dias a esperar após tentativa de exibição bloqueada |
waitDaysAfterWidgetFirstAccess | number | 0 | Dias a esperar após o primeiro acesso do usuário à jornada |
waitDaysAfterWidgetDisplay | number | 0 | Dias a esperar após qualquer exibição do widget |
waitDaysAfterWidgetDismiss | number | 0 | Dias a esperar após o usuário fechar o widget |
waitDaysAfterWidgetSubmit | number | 0 | Dias a esperar após envio completo da pesquisa |
waitDaysAfterWidgetPartialSubmit | number | 0 | Dias a esperar após envio parcial da pesquisa |
Dica: Valor 0 nos campos de dias = sem restrição (o campo não bloqueia). As configurações podem ser gerenciadas remotamente pelo painel da jornada — assim você não precisa atualizar o app para mudar as regras.
Importante sobre Quarentena: O controle de quarentena do widget é baseado em cookies do navegador do cliente. Isso significa que a quarentena não é 100% garantida, pois o usuário pode limpar os cookies, usar navegadores diferentes, dispositivos diferentes ou modo de navegação anônima/privada. Para cenários que exigem controle rigoroso de quarentena, recomendamos implementar validações adicionais no lado do servidor.
WidgetCallbacks
Funções chamadas em cada etapa do ciclo de vida do widget. Todas são opcionais.
Ciclo de vida
Ao chamar .show(), o SDK executa os seguintes passos:
- Verifica as opções locais (enabled, amostragem, tentativas, intervalos)
- Se bloqueado: chama
onBlockedcom o motivo e o widget não aparece - Se liberado: solicita a URL da pesquisa à API SoluCX (preflight)
- Chama
onPreOpen→ exibe o widget → chamaonOpened - Durante a pesquisa, o usuário interage com o formulário
- Quando o usuário responde a nota principal (NPS/CSAT/CES): chama
onPartialCompleted - Quando o usuário conclui toda a pesquisa: chama
onCompleted - Ao fechar (pelo usuário ou automaticamente): chama
onClosed - Se ocorrer erro em qualquer etapa: chama
onError
A validação das regras de exibição é feita localmente, antes de chamar a API, para reduzir a carga no servidor.
Descrição dos callbacks
| Callback | Parâmetro | Quando é chamado |
|---|---|---|
onPreOpen | userId: string | Imediatamente antes do widget ser exibido, após a validação das regras de exibição passar |
onOpened | userId: string | Quando o widget é exibido na tela |
onBlocked | reason: BlockReason | Quando as regras de exibição impedem o widget de ser exibido. Veja BlockReason |
onClosed | - | Quando o widget é fechado, seja pelo usuário ou automaticamente |
onCompleted | userId: string | Quando o usuário conclui toda a pesquisa (todas as etapas) |
onPartialCompleted | userId: string | Quando o usuário responde a nota principal (NPS/CSAT/CES) |
onError | message: string | Quando ocorre um erro na pesquisa (pesquisa expirada, já avaliada, falha de rede) |
onPageChanged | page: string | Quando o usuário navega entre páginas (Flex Survey) |
onQuestionAnswered | - | Quando o usuário responde uma pergunta (Flex Survey) |
onResize | height: string | Quando a altura do widget muda |
BlockReason
Motivos pelos quais as regras de exibição impedem o widget de ser exibido. Esses bloqueios são locais (no dispositivo) e não representam erros da API.
| Razão | Descrição |
|---|---|
BLOCKED_BY_DISABLED | Widget desabilitado (enabled: false) |
BLOCKED_BY_SAMPLING | Usuário não foi selecionado pela amostragem (samplingPercentage) |
BLOCKED_BY_TRANSACTION_ALREADY_ANSWERED | Transação já foi respondida anteriormente |
BLOCKED_BY_MAX_ATTEMPTS | Número máximo de tentativas atingido para esta experiência |
BLOCKED_BY_WIDGET_DISPLAY_ATTEMPT_INTERVAL | Dentro do intervalo após tentativa de exibição |
BLOCKED_BY_WIDGET_FIRST_ACCESS_INTERVAL | Dentro do intervalo após primeiro acesso à jornada |
BLOCKED_BY_WIDGET_DISPLAY_INTERVAL | Dentro do intervalo após exibição |
BLOCKED_BY_WIDGET_DISMISS_INTERVAL | Dentro do intervalo após fechamento |
BLOCKED_BY_WIDGET_SUBMIT_INTERVAL | Dentro do intervalo após envio completo |
BLOCKED_BY_WIDGET_PARTIAL_SUBMIT_INTERVAL | Dentro do intervalo após envio parcial |
Múltiplos Widgets
Cada combinação de instanceKey + journey + userId opera com logs independentes:
Troubleshooting
Widget não aparece
- Verifique se a chave SoluCX (
soluCXKey) é válida - Verifique se há conectividade com a internet
- Use o callback
onBlockedpara verificar se as regras de exibição estão impedindo a exibição - Use o callback
onErrorpara verificar se há erros na pesquisa
Callbacks não são chamados
- Confirme que o objeto
callbacksestá sendo passado via.setCallbacks()ou como prop doSoluCXWidgetView - Verifique o console para mensagens de erro do WebView
Layout quebrado
- Defina uma altura fixa via
setOptions({ height: 600 })se o redimensionamento automático não funcionar bem no seu layout - Para o modo
inline, certifique-se de que o componente pai tem espaço suficiente
Compatibilidade
| Versão | React Native | Expo | iOS | Android |
|---|---|---|---|---|
| 2.x | 0.70+ | 50+ | 11+ | API 21+ |
Licença
Este pacote é proprietário da SoluCX. O uso é restrito a clientes licenciados da plataforma SoluCX.