Pular para o conteúdo principal

Documentation Index

Fetch the complete documentation index at: https://docs.nemu.com.br/llms.txt

Use this file to discover all available pages before exploring further.

Introdução

O Nemu React Native SDK (@usenemu-account/react-native-sdk) permite integrar o sistema de atribuição e Smart Links da Nemu diretamente no seu aplicativo React Native. Com o SDK você pode:
  • Capturar a origem da instalação — saber de qual campanha, fonte ou mídia o usuário veio (UTMs)
  • Processar deep links diretos — quando o usuário clica em um Smart Link e o app já está instalado
  • Processar deep links diferidos — quando o usuário clica em um Smart Link, instala o app pela loja e abre pela primeira vez
  • Identificar usuários — associar um ID do seu sistema ao dispositivo para cruzar dados de atribuição
  • Consultar histórico de sessões — recuperar os UTMs da última interação do usuário
O SDK funciona de forma automática: ao ser inicializado, ele intercepta deep links, detecta se é a primeira abertura do app e realiza a atribuição com o backend da Nemu, sem necessidade de configuração manual de cada evento.

Pré-requisitos

RequisitoVersão mínima
React Native>= 0.70.0
React>= 17.0.0
Node.js>= 16 LTS
npm ou YarnVersão compatível com Node 16+
iOSSuporte a CocoaPods
AndroidAPI 21+ (Android 5.0)
Pacote privado: o @usenemu-account/react-native-sdk é um pacote npm de acesso restrito. Para instalá-lo, você precisa de um token npm fornecido pela equipe de suporte da Nemu. Consulte a seção de instalação abaixo.

Instalação

1. Configuração do token npm

O pacote @usenemu-account/react-native-sdk é privado e está publicado no registro npm com acesso restrito. Antes de instalar, você precisa configurar a autenticação.

Obtenha seu token

Entre em contato com a equipe de suporte da Nemu para receber seu token de acesso npm:

Configure o arquivo .npmrc

Na raiz do seu projeto (mesmo diretório do package.json), crie ou edite o arquivo .npmrc:
//registry.npmjs.org/:_authToken=SEU_TOKEN_NPM_AQUI
Substitua SEU_TOKEN_NPM_AQUI pelo token recebido do suporte.
Segurança: adicione o .npmrc ao seu .gitignore para não versionar o token no repositório:
echo ".npmrc" >> .gitignore
Para ambientes de CI/CD, configure o token como variável de ambiente:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

2. Instalação do pacote

Com o token configurado, instale o SDK:
# npm
npm install @usenemu-account/react-native-sdk

# ou Yarn
yarn add @usenemu-account/react-native-sdk

3. Dependências obrigatórias (peer dependencies)

O SDK requer as seguintes bibliotecas como peer dependencies. Instale-as caso ainda não estejam no seu projeto:
# npm
npm install @react-native-async-storage/async-storage react-native-keychain react-native-device-info

# ou Yarn
yarn add @react-native-async-storage/async-storage react-native-keychain react-native-device-info
DependênciaVersão mínimaFinalidade
@react-native-async-storage/async-storage>= 1.17.0Armazenamento local de dados de sessão e atribuição
react-native-keychain>= 8.0.0Armazenamento seguro do identificador do dispositivo
react-native-device-info>= 10.0.0Recupera informações do dispositivo

Configuração nativa

iOS

1. Instale os Pods

Após instalar as dependências JavaScript, execute o CocoaPods:
cd ios && pod install && cd ..
Para que o iOS encaminhe os Smart Links diretamente para o app (sem abrir o navegador), você precisa configurar Associated Domains. No Xcode:
  1. Abra o projeto .xcworkspace
  2. Selecione o target do app
  3. Vá em Signing & Capabilities
  4. Clique em + Capability e adicione Associated Domains
  5. Adicione o domínio no formato:
applinks:seu-dominio.nemu.com.br
O domínio exato será fornecido pela equipe da Nemu junto com as credenciais.

3. Configure o URI Scheme (obrigatório)

No arquivo Info.plist, adicione o URI scheme do seu app:
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>seuapp</string>
    </array>
  </dict>
</array>
Substitua seuapp pelo scheme definido no painel da Nemu para o seu Smart Link.

Android

Para que os Smart Links abram o app diretamente, adicione intent filters na sua Activity principal. No arquivo android/app/src/main/AndroidManifest.xml, dentro da tag <activity> principal: App Links (Universal Links do Android):
<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data
    android:scheme="https"
    android:host="seu-dominio.nemu.com.br" />
</intent-filter>
URI Scheme:
<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="seuapp" />
</intent-filter>
Substitua seu-dominio.nemu.com.br e seuapp pelos valores correspondentes ao seu projeto.

2. Permissão de Internet (geralmente já presente)

Verifique se o AndroidManifest.xml possui a permissão de internet:
<uses-permission android:name="android.permission.INTERNET" />
Na maioria dos projetos React Native essa permissão já está incluída por padrão.

Inicialização

A inicialização do SDK deve ser feita uma única vez, no componente raiz do app (geralmente App.tsx), dentro de um useEffect.

Parâmetros de configuração

ParâmetroTipoObrigatórioDescrição
apiKeystringSimChave de API obtida no painel da Nemu
uriSchemestringSimURI scheme do app (ex: "seuapp"). Deve corresponder ao valor configurado no Smart Link
trackingIdstringSimID de rastreamento associado ao app no painel da Nemu
isDebugModebooleanNãoAtiva logs detalhados no console. Padrão: false
baseUrlstringNãoSobrescreve a URL base da API

Exemplo completo de inicialização

import React, { useEffect } from 'react';
import { NemuTracking } from '@usenemu-account/react-native-sdk';

function App() {
  useEffect(() => {
    NemuTracking.init({
      apiKey: 'sua-api-key',
      uriScheme: 'seuapp',
      trackingId: 'seu-tracking-id',
    });
  }, []);

  return (
    // ... seu app
  );
}

export default App;

Uso com variáveis de ambiente

Para não expor credenciais diretamente no código, utilize o pacote react-native-config ou similar:
import Config from 'react-native-config';
import { NemuTracking } from '@usenemu-account/react-native-sdk';

useEffect(() => {
  NemuTracking.init({
    apiKey: Config.NEMU_API_KEY!,
    uriScheme: Config.NEMU_URI_SCHEME!,
    trackingId: Config.NEMU_TRACKING_ID!,
  });
}, []);
Com o .env correspondente:
NEMU_API_KEY=sua-api-key
NEMU_URI_SCHEME=seuapp
NEMU_TRACKING_ID=seu-tracking-id

Identificação de usuários

Após o login do usuário no seu app, associe o ID dele ao dispositivo. Isso permite que a Nemu cruze dados de atribuição com o seu sistema de usuários.

Registrar usuário

import { NemuTracking } from '@usenemu-account/react-native-sdk';

// Após o login bem-sucedido
function onLoginSuccess(userId: string) {
  NemuTracking.setUserId(userId);
}
O SDK salva o ID localmente e envia a associação ao backend automaticamente.

Limpar usuário no logout

function onLogout() {
  NemuTracking.clearUserId();
}
Nota: clearUserId() remove apenas a associação local. O histórico de atribuição no backend é preservado.

O SDK processa dois tipos de deep links automaticamente: Ocorrem quando o app já está instalado e o usuário clica em um Smart Link. O sistema operacional abre o app diretamente (via Universal Link / App Link ou URI scheme). O fluxo é transparente:
  1. O usuário clica no Smart Link
  2. O app abre com a URL
  3. O SDK processa a URL e registra a sessão
  4. Os listeners registrados via onDeepLink são notificados com os dados
Ocorrem quando o app não está instalado. O usuário clica no Smart Link, é redirecionado para a loja, instala o app e abre pela primeira vez. O SDK detecta automaticamente esse cenário na primeira abertura e entrega os dados de atribuição e deep link via onDeepLink com isDeferred: true. Registre um callback para receber os dados do deep link assim que estiverem disponíveis:
import React, { useEffect } from 'react';
import { NemuTracking } from '@usenemu-account/react-native-sdk';
import type { DeepLinkData } from '@usenemu-account/react-native-sdk';

function App() {
  useEffect(() => {
    NemuTracking.init({
      apiKey: 'sua-api-key',
      uriScheme: 'seuapp',
      trackingId: 'seu-tracking-id',
    });

    const unsubscribe = NemuTracking.onDeepLink((data: DeepLinkData) => {
      console.log('Deep link recebido:', data);

      if (data.deepLinkValue) {
        // Navegar para a tela correspondente
        // Ex: data.deepLinkValue = "product/456"
        navigateTo(data.deepLinkValue);
      }

      if (data.utms) {
        console.log('Fonte:', data.utms.source);
        console.log('Campanha:', data.utms.campaign);
      }

      console.log('Foi diferido?', data.isDeferred);
    });

    // Limpar listener ao desmontar
    return () => unsubscribe();
  }, []);

  return (/* ... */);
}
Replay automático: se um deep link já foi processado antes do listener ser registrado, o callback é disparado imediatamente com os dados mais recentes. Isso evita que o app perca o deep link inicial.

Consulta imperativa (getDeepLinkData)

Se preferir consultar os dados de forma imperativa em vez de usar o listener:
async function checkDeepLink() {
  const data = await NemuTracking.getDeepLinkData();

  if (data) {
    console.log('App aberto via Smart Link:', data.deepLinkValue);
  } else {
    console.log('App aberto organicamente');
  }
}

Estrutura do DeepLinkData

interface DeepLinkData {
  /** Valor do deep link (ex: "product/456", "category/shoes") */
  deepLinkValue: string | null;

  /** true = deep link diferido (usuário instalou após clicar) */
  isDeferred: boolean;

  /** Parâmetros UTM do Smart Link */
  utms: {
    source: string | null;
    medium: string | null;
    campaign: string | null;
    content: string | null;
    term: string | null;
  } | null;
}

Atribuição

Histórico da última sessão (last touch)

Consulte os UTMs da interação mais recente do usuário. Responde à pergunta: “quais foram os UTMs da última visita?”
async function checkLastSession() {
  const session = await NemuTracking.getLastSessionHistory();

  if (session) {
    console.log('Fonte:', session.utm_source);
    console.log('Mídia:', session.utm_medium);
    console.log('Campanha:', session.utm_campaign);
    console.log('Conteúdo:', session.utm_content);
    console.log('Termo:', session.utm_term);
  } else {
    console.log('Nenhuma sessão encontrada');
  }
}

Inserção manual de histórico de UTM (setSessionHistory)

Use setSessionHistory quando você precisa registrar UTMs manualmente em fluxos personalizados (por exemplo, campanha definida pelo backend, onboarding interno ou regra de negócio que não depende de deep link).
NemuTracking.setSessionHistory({
  utm_source: 'newsletter',
  utm_medium: 'email',
  utm_campaign: 'black_friday_2026',
  utm_content: 'cta_header',
  utm_term: 'ofertas',
});
ParâmetroTipoObrigatórioDescrição
utm_sourcestringSimOrigem da campanha
utm_mediumstring | nullNãoMídia/canal
utm_campaignstring | nullNãoNome da campanha
utm_contentstring | nullNãoConteúdo da peça
utm_termstring | nullNãoTermo adicional
Comportamento importante:
  • utm_source é obrigatório; chamadas inválidas são ignoradas com segurança
  • O método reutiliza o fluxo interno de sessão/histórico do SDK (trackEvent)
  • Existe desduplicação para evitar criação excessiva de históricos em chamadas repetidas
  • A execução é assíncrona e resiliente (falhas internas não devem quebrar o app)
Quando usar: se a origem já veio por Smart Link/deep link com UTMs válidos, prefira o fluxo automático. Use setSessionHistory para complementar cenários não cobertos pelo link.

Exemplo: anexando UTMs a uma compra

async function trackPurchase(orderId: string, amount: number) {
  const lastSession = await NemuTracking.getLastSessionHistory();

  const purchasePayload = {
    orderId,
    amount,
    lastSource: lastSession?.utm_source ?? null,
    lastCampaign: lastSession?.utm_campaign ?? null,
    lastMedium: lastSession?.utm_medium ?? null,
    lastContent: lastSession?.utm_content ?? null,
    lastTerm: lastSession?.utm_term ?? null,
  };

  // Enviar para o seu backend
  await fetch('https://sua-api.com/purchases', {
    method: 'POST',
    body: JSON.stringify(purchasePayload),
  });
}

Integração com WebView

Quando o app embute conteúdo web via WebView e a página precisa consumir os dados de atribuição (por exemplo, os UTMs retornados por getLastSessionHistory), o SDK roda apenas no lado nativo (React Native). Para que a página web tenha acesso a esses dados, você precisa criar uma ponte bidirecional entre o React Native e a WebView.

Estratégia recomendada

A abordagem mais confiável combina dois mecanismos:
  • Pré-injeção: os dados são disponibilizados como variável global na WebView antes do carregamento do conteúdo
  • Bridge sob demanda: a página web pode solicitar uma versão atualizada do histórico a qualquer momento
Por que não usar query params na URL? É a abordagem mais simples, mas tem limite de tamanho, expõe os dados na URL e não permite atualizar valores sem recarregar a página. Use apenas quando os dados são pequenos e estáticos.

Implementação no React Native

import React, { useEffect, useRef, useState } from 'react';
import { WebView, type WebViewMessageEvent } from 'react-native-webview';
import { NemuTracking } from '@usenemu-account/react-native-sdk';
import type { TrackingSessionHistory } from '@usenemu-account/react-native-sdk';

function ScreenWithWebView() {
  const webRef = useRef<WebView>(null);
  const [initialHistory, setInitialHistory] =
    useState<TrackingSessionHistory | null | undefined>(undefined);

  useEffect(() => {
    NemuTracking.getLastSessionHistory().then(setInitialHistory);
  }, []);

  // Aguarda a consulta inicial antes de montar a WebView
  if (initialHistory === undefined) return null;

  const preload = `
    window.__NEMU_HISTORY__ = ${JSON.stringify(initialHistory)};
    window.nemuRequestHistory = function () {
      window.ReactNativeWebView.postMessage(
        JSON.stringify({ type: 'NEMU_GET_HISTORY' })
      );
    };
    true;
  `;

  const onMessage = async (event: WebViewMessageEvent) => {
    try {
      const msg = JSON.parse(event.nativeEvent.data);
      if (msg.type === 'NEMU_GET_HISTORY') {
        const history = await NemuTracking.getLastSessionHistory();
        webRef.current?.injectJavaScript(`
          window.dispatchEvent(new CustomEvent('nemu:history', {
            detail: ${JSON.stringify(history)}
          }));
          true;
        `);
      }
    } catch {
      // Ignora mensagens fora do protocolo
    }
  };

  return (
    <WebView
      ref={webRef}
      source={{ uri: 'https://sua-pagina.com' }}
      injectedJavaScriptBeforeContentLoaded={preload}
      onMessage={onMessage}
    />
  );
}

Consumo no lado web

Dentro da página carregada na WebView, os dados ficam disponíveis logo no carregamento e podem ser atualizados sob demanda:
// Acesso imediato no carregamento
const history = window.__NEMU_HISTORY__;
console.log('UTMs da última sessão:', history);

// Receber atualizações quando o React Native responder a uma solicitação
window.addEventListener('nemu:history', (event) => {
  console.log('Histórico atualizado:', event.detail);
});

// Solicitar uma versão atualizada
window.nemuRequestHistory();

Considerações importantes

  • Aguarde o init do SDK antes de montar a WebView. Chamar getLastSessionHistory() antes de NemuTracking.init() faz a Promise ser rejeitada.
  • Sanitização do JSON: ao injetar dados na WebView, sempre use JSON.stringify. Nunca interpole strings diretamente para evitar XSS caso algum campo venha de fonte externa.
  • injectedJavaScriptBeforeContentLoaded: requer react-native-webview >= 11. Em versões anteriores, use injectedJavaScript (executa após o DOM carregar — pode haver race condition com scripts da página).
  • Detecção do ambiente: se a mesma página web também roda fora da WebView (no navegador), trate window.ReactNativeWebView como opcional para evitar erros:
const isInWebView = typeof window.ReactNativeWebView !== 'undefined';

if (isInWebView) {
  window.nemuRequestHistory();
}

Uso avançado

Modo debug

Ative o modo debug para ver logs detalhados de todas as operações do SDK no console:
NemuTracking.init({
  apiKey: 'sua-api-key',
  uriScheme: 'seuapp',
  trackingId: 'seu-tracking-id',
  isDebugMode: true,
});
Os logs aparecerão prefixados com [NemuSDK] e incluem informações sobre:
  • Processamento de deep links
  • Fluxo de inicialização
  • Erros e falhas de rede
Importante: desative o modo debug em produção. Os logs podem conter informações sensíveis.

Sobrescrita da URL base

Em ambiente de desenvolvimento ou staging, você pode apontar o SDK para uma API diferente:
NemuTracking.init({
  apiKey: 'sua-api-key',
  uriScheme: 'seuapp',
  trackingId: 'seu-tracking-id',
  isDebugMode: true,
  baseUrl: 'https://staging-trackings.nemu.com.br',
});
A baseUrl só é utilizada quando isDebugMode é true. Em modo de produção, o SDK sempre usa a URL padrão.

Solução de problemas

Erro de autenticação npm ao instalar

Erro:
npm ERR! 401 Unauthorized - GET https://registry.npmjs.org/@usenemu%2freact-native-sdk
Solução:
  • Verifique se o arquivo .npmrc existe na raiz do projeto
  • Confirme que o token está correto e não expirou
  • Entre em contato com o suporte da Nemu para validar ou renovar o token

Erro “NemuTracking.init() must be called before using any other method”

Causa: um método do SDK foi chamado antes da inicialização. Solução: certifique-se de que NemuTracking.init() é chamado no useEffect do componente raiz antes de qualquer outro método do SDK.

Pod install falha no iOS

Erro:
[!] Unable to find a specification for `react-native-keychain`
Solução:
  1. Verifique se react-native-keychain está instalado como dependência JavaScript
  2. Execute:
    cd ios
    pod deintegrate
    pod install
    

Verificações:
  • O Associated Domain está configurado corretamente no Xcode? (formato: applinks:seu-dominio)
  • O arquivo apple-app-site-association está publicado e acessível no domínio? (configurado pela equipe da Nemu)
  • O URI scheme está declarado no Info.plist?

Verificações:
  • Os intent filters estão corretos no AndroidManifest.xml?
  • O domínio está com verificação automática ativa (android:autoVerify="true")?
  • O arquivo assetlinks.json está publicado no domínio? (configurado pela equipe da Nemu)

Nenhum dado de atribuição retornado

Verificações:
  • O apiKey e o trackingId estão corretos?
  • O Smart Link está configurado e ativo no painel da Nemu?
  • Teste com isDebugMode: true e verifique os logs [NemuSDK] no console