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
| Requisito | Versão mínima |
|---|
| React Native | >= 0.70.0 |
| React | >= 17.0.0 |
| Node.js | >= 16 LTS |
| npm ou Yarn | Versão compatível com Node 16+ |
| iOS | Suporte a CocoaPods |
| Android | API 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:
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ência | Versão mínima | Finalidade |
|---|
@react-native-async-storage/async-storage | >= 1.17.0 | Armazenamento local de dados de sessão e atribuição |
react-native-keychain | >= 8.0.0 | Armazenamento seguro do identificador do dispositivo |
react-native-device-info | >= 10.0.0 | Recupera 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:
- Abra o projeto
.xcworkspace
- Selecione o target do app
- Vá em Signing & Capabilities
- Clique em + Capability e adicione Associated Domains
- 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.
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âmetro | Tipo | Obrigatório | Descrição |
|---|
apiKey | string | Sim | Chave de API obtida no painel da Nemu |
uriScheme | string | Sim | URI scheme do app (ex: "seuapp"). Deve corresponder ao valor configurado no Smart Link |
trackingId | string | Sim | ID de rastreamento associado ao app no painel da Nemu |
isDebugMode | boolean | Não | Ativa logs detalhados no console. Padrão: false |
baseUrl | string | Não | Sobrescreve 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;
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.
Deep Links
O SDK processa dois tipos de deep links automaticamente:
Deep links diretos
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:
- O usuário clica no Smart Link
- O app abre com a URL
- O SDK processa a URL e registra a sessão
- Os listeners registrados via
onDeepLink são notificados com os dados
Deep links diferidos (Deferred Deep Links)
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.
Listener reativo (onDeepLink)
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âmetro | Tipo | Obrigatório | Descrição |
|---|
utm_source | string | Sim | Origem da campanha |
utm_medium | string | null | Não | Mídia/canal |
utm_campaign | string | null | Não | Nome da campanha |
utm_content | string | null | Não | Conteúdo da peça |
utm_term | string | null | Não | Termo 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),
});
}
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:
- Verifique se
react-native-keychain está instalado como dependência JavaScript
- Execute:
cd ios
pod deintegrate
pod install
Deep links não funcionam no iOS
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?
Deep links não funcionam no Android
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