Identifique visitantes, registre contatos e eventos, acompanhe sessões e origens de tráfego e habilite web push no seu site.
Com o SDK instalado, cada visitante do seu site recebe uma identidade persistente, o reachyID. A partir dela o Reachy monta a linha do tempo do contato: páginas vistas, origem da visita, eventos do seu negócio, cadastro, inscrição em web push. Esses dados alimentam Públicos, Jornadas e Campanhas.
createContact e o visitante vira um contato no Reachy.trackEvent.Tudo chega ao Reachy em segundos e aparece na aba Contacts do projeto.
| No site | No Reachy |
|---|---|
createContact | Um contato no projeto, com nome, e-mail, telefone, campos customizados e preferências de comunicação por canal |
trackEvent e eventos automáticos | Eventos na linha do tempo do contato, filtráveis em Públicos e usáveis como gatilho em Jornadas |
properties do contato | Campos do contato, para filtro e personalização de mensagens |
| UTMs da visita | Origem da sessão, enviada em todo evento |
identify | Vínculo do visitante a um ID do seu sistema |
| Web push | Navegador do visitante vinculado ao contato como dispositivo |
| Descadastro | Página de descadastro no seu site que atualiza as preferências do contato |
O SDK pesa cerca de 73 KB, carrega de forma assíncrona e não atrasa a página. Ele funciona em sites estáticos, WordPress, aplicações React, Next.js, Vue e qualquer outra tecnologia que renderize HTML no navegador.
O passcode é a chave que liga o site ao projeto no Reachy. Todo contato e evento enviados com ele caem nesse projeto.
site-institucional, quiz-cartao), escolha se expira e confirme.Detalhes de criação, expiração e revogação em Passcodes.
Em cerca de 15 minutos o site envia page views sozinho, cadastra um contato e dispara um evento que aparece no Reachy.
Cole o bloco em todas as páginas, antes do </head>, trocando o passcode pelo do seu projeto.
<script>
window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
window.reachy.queue.push({ type: 'config', data: {
passcode: 'YOUR_PASSCODE'
}});
</script>
<script async src="https://sdk.reachy.io/sdk.js"></script>Ao carregar, o SDK lê a configuração em window.reachy.queue, cria a instância global window.MySDK e envia o primeiro page_enter.
No envio do seu formulário, chame reachy.event.push com um objeto. Precisa de e-mail ou telefone.
reachy.event.push({
email: 'ana@email.com',
first_name: 'Ana',
phone: '+5511999999999',
is_subscribed: true, // consent checked on the form
properties: { source: 'quiz', plan: 'basic' }
});Com um nome e um objeto, a mesma chamada registra um evento na linha do tempo do contato.
reachy.event.push('Form Completed', {
source: 'quiz',
'Has a credit card?': 'Yes'
});Cadastre o contato antes de enviar o evento de conversão, para o evento já chegar ligado à pessoa.
Abra a página com ?reachy_debug=true no final da URL: um painel mostra o reachyID, a sessão e cada evento no momento do envio. No Reachy, em Contacts, o contato aparece em até 1 minuto com os campos e o evento na aba de atividades.
Próximos passos
O snippet do Início rápido funciona em qualquer site. Esta seção mostra onde colocá-lo em cada plataforma e como chamar o SDK a partir de código que roda antes de o script terminar de carregar.
Cole o snippet no <head> de todas as páginas (ou no template compartilhado). Chamadas feitas depois do carregamento usam reachy.event.push, reachy.identify.push e as demais filas, ou window.MySDK direto.
window.reachy.event.push(...) nelas; a fila garante a ordem.Carregue o SDK por um componente único no layout, com o passcode em variável de ambiente. A configuração é aplicada no onload do script via MySDK.updateConfig.
"use client";
import Script from "next/script";
export default function ReachyScripts({ passcode }: { passcode?: string }) {
if (!passcode) return null;
const config = { passcode, trackClicks: false };
const loader = `
window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
var s = document.createElement('script');
s.async = true;
s.src = 'https://sdk.reachy.io/sdk.js';
s.onload = function () { window.MySDK.updateConfig(${JSON.stringify(config)}); };
document.head.appendChild(s);
`;
return <Script id="reachy-sdk" strategy="afterInteractive" dangerouslySetInnerHTML={{ __html: loader }} />;
}No layout: <ReachyScripts passcode={process.env.NEXT_PUBLIC_REACHY_PASSCODE} />.
Em componentes, não chame window.reachy direto. Use um helper que espera o SDK ficar pronto (window.MySDK.initialized) e envie o evento de conversão depois do cadastro:
declare global { interface Window { MySDK?: any } }
// Runs fn as soon as the SDK is loaded and initialized
export function whenReady(fn: (sdk: any) => void) {
if (typeof window === 'undefined') return;
if (window.MySDK?.initialized) return fn(window.MySDK);
const timer = setInterval(() => {
if (window.MySDK?.initialized) { clearInterval(timer); fn(window.MySDK); }
}, 50);
}
// Contact first, conversion event second
whenReady((sdk) => sdk.createContact({ email, first_name: firstName, is_subscribed: true }));
whenReady((sdk) => sdk.trackEvent('Form Completed', { source: 'quiz' }));O mesmo padrão: carregue https://sdk.reachy.io/sdk.js uma vez na inicialização da aplicação, aplique a configuração no onload com window.MySDK.updateConfig({ passcode }) e use window.MySDK nos componentes. Em aplicações de página única (SPA), o SDK detecta a troca de rota pela History API e envia page_enter a cada tela sem código extra.
O script precisa rodar em todas as páginas, então o lugar certo é o <head> do site, não um widget dentro de uma página. Escolha um dos caminhos e use sempre o mesmo snippet.
| Caminho | Requer | Cobre |
|---|---|---|
| Elementor > Custom Code | Elementor Pro | Site inteiro. Recomendado. |
| Plugin WPCode > Header & Footer | Plugin gratuito | Site inteiro. |
| Widget HTML na página | Nada | Só aquela página. Use apenas para testes. |
A primeira linha do snippet abaixo evita registrar visitas dentro do editor do Elementor, cuja URL de pré-visualização contém elementor-preview. Informe o domínio raiz em cookieDomain para o visitante ser o mesmo em www, loja. e blog..
<!-- Reachy SDK -->
<script>
if (location.search.indexOf('elementor-preview') === -1) {
window.reachy = window.reachy || { event: [], config: [], session: [], privacy: [], identify: [], login: [], queue: [] };
window.reachy.queue.push({ type: 'config', data: {
passcode: 'YOUR_PASSCODE',
cookieDomain: 'yoursite.com' // root domain, without www
}});
var s = document.createElement('script');
s.async = true;
s.src = 'https://sdk.reachy.io/sdk.js';
document.head.appendChild(s);
}
</script>Com Elementor Pro: Elementor > Custom Code > Add New; nome Reachy SDK, Location <head>, Priority 1; cole o snippet, clique em Publish e escolha Entire Site.
Sem Elementor Pro: instale e ative o plugin WPCode; em Code Snippets > Header & Footer, cole o snippet na caixa Header e salve.
Formulários do Elementor Pro: o SDK não lê formulários sozinho. No widget Form, defina o ID de cada campo (aba Advanced) como nome, email e telefone, e adicione o código abaixo em um widget HTML da página ou no Custom Code para valer em todo o site. O envio usa sendBeacon, então o contato é criado mesmo que o formulário redirecione.
<script>
document.addEventListener('submit', function (e) {
var form = e.target;
if (!form.classList || !form.classList.contains('elementor-form')) return;
var get = function (id) {
var el = form.querySelector('[name="form_fields[' + id + ']"]');
return el ? el.value.trim() : '';
};
var email = get('email'), phone = get('telefone');
if (!email && !phone) return;
reachy.login.push({
first_name: get('nome'),
email: email || undefined,
phone: phone || undefined,
is_subscribed: true,
properties: { source: 'elementor', form: form.getAttribute('name') || form.id || 'form', page: location.pathname }
});
reachy.event.push('Form Completed', { page: location.pathname });
}, true);
</script>WooCommerce: os eventos de e-commerce ficam em MySDK.ecommerce e precisam esperar a instância existir. Gere o JavaScript pelo PHP, com os dados reais do pedido, no functions.php do tema filho ou em um snippet PHP do WPCode. O mesmo padrão vale para checkoutStarted na página de checkout.
add_action('woocommerce_thankyou', function ($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
$items = [];
foreach ($order->get_items() as $item) {
$p = $item->get_product();
$items[] = [
'product_id' => $p && $p->get_sku() ? $p->get_sku() : (string) $item->get_product_id(),
'name' => $item->get_name(),
'price' => $item->get_quantity() ? (float) $item->get_total() / $item->get_quantity() : 0,
'quantity' => (int) $item->get_quantity(),
];
}
$data = [
'order_id' => (string) $order->get_order_number(),
'total' => (float) $order->get_total(),
'shipping' => (float) $order->get_shipping_total(),
'tax' => (float) $order->get_total_tax(),
'currency' => $order->get_currency(),
'payment_method' => $order->get_payment_method(),
'coupon' => implode(',', $order->get_coupon_codes()) ?: null,
'items' => $items,
];
$contact = [
'first_name' => $order->get_billing_first_name(),
'email' => $order->get_billing_email(),
'phone' => $order->get_billing_phone(),
'is_subscribed' => true,
];
?>
<script>
reachy.login.push(<?php echo wp_json_encode($contact); ?>);
(function wait(n) {
if (window.MySDK && MySDK.initialized) MySDK.ecommerce.orderCompleted(<?php echo wp_json_encode($data); ?>);
else if (n < 200) setTimeout(function () { wait(n + 1); }, 50);
})(0);
</script>
<?php
});Plugins de cache e otimização: opções que atrasam JavaScript seguram o SDK até o primeiro clique ou rolagem, e quem entra e sai sem interagir não gera page_enter. Adicione sdk.reachy.io e reachy às exclusões e limpe o cache após cada alteração.
| Plugin | Opção | O que fazer |
|---|---|---|
| WP Rocket | Delay JavaScript execution, Minify/Combine JS | Em File Optimization, adicione sdk.reachy.io e reachy às exclusões de delay e de minificação. |
| LiteSpeed Cache | JS Delay, JS Combine | Em Page Optimization > Tuning, adicione sdk.reachy.io e reachy em JS Excludes e JS Delayed Excludes. |
| Autoptimize | Aggregate JS, Defer | Exclua sdk.reachy.io e reachy em JS Optimization. |
| Cloudflare | Rocket Loader | Desligue ou adicione data-cfasync="false" na tag <script> do snippet. |
| Qualquer cache de página | HTML antigo em cache | Limpe o cache após cada alteração no snippet ou nos widgets HTML. |
Qualquer comando pode ser colocado em window.reachy.queue antes do script, no formato { type, data }. O SDK executa tudo na ordem assim que inicia.
type | data |
|---|---|
config | objeto de configuração |
createContact | dados do contato |
trackEvent | { eventName, eventData } |
identify | { userId, traits } |
webpush | { action: 'requestPermission' | 'unsubscribe', options } |
renewSession, clearSession | nenhum |
Depois do carregamento, as filas nomeadas executam na hora: reachy.event.push, reachy.login.push, reachy.identify.push, reachy.webpush.push, reachy.session.push, reachy.privacy.push e reachy.config.push.
Na primeira visita o SDK gera um identificador único para o navegador, o reachyID, e o guarda por 1 ano em localStorage e cookie. Todo evento leva esse ID; é por ele que o Reachy liga a navegação ao contato. Com a opção cookieDomain, o mesmo reachyID vale em todos os subdomínios do site.
Um visitante passa por dois estados:
reachyID, sessão e eventos, mas o Reachy ainda não sabe quem é. Aparece em métricas de tráfego, não em Contacts.createContact, vira um contato com e-mail ou telefone. A partir daí os eventos entram na linha do tempo dele e ele pode receber mensagens.createContact(data) cria o contato ou atualiza o existente. Via fila: reachy.event.push({ ... }) com um objeto, ou reachy.login.push({ ... }).
MySDK.createContact({
email: 'ana@email.com',
phone: '+5511999999999',
first_name: 'Ana',
last_name: 'Souza',
is_subscribed: true,
properties: { plan: 'basic', source: 'quiz', utm_source: 'google' }
});| Campo | Obrigatório | Descrição |
|---|---|---|
email | Um dos dois | E-mail do contato. É a identidade principal. |
phone | Um dos dois | Telefone em formato internacional (+5511999999999), com 6 dígitos ou mais. whatsapp é aceito como sinônimo. |
first_name, last_name | Não | Nome e sobrenome. |
is_subscribed | Não (padrão true) | Consentimento para receber mensagens. Define as preferências por canal. |
properties | Não | Objeto com campos do contato. Use nomes em snake_case e os mesmos nomes em todos os sites. |
communication_preferences | Não | Controle fino por canal (ver abaixo). Se omitido, o SDK deriva de is_subscribed. |
Regras:
false.reachyID para o contato. Isso evita juntar duas pessoas que usam o mesmo dispositivo. Cadastros só com telefone sempre geram um ID novo.MySDK.updateUserData({ email }). O SDK reconhece o e-mail e reaproveita o reachyID, e as páginas vistas e a inscrição de web push feitas antes do formulário ficam no contato.is_subscribed: e-mail fica ativo se há e-mail e consentimento; SMS e WhatsApp, se há telefone e consentimento; web push começa desativado. Para controle fino, envie communication_preferences com a lista channels:communication_preferences: {
channels: [
{ channel: 'email', subscribed: true },
{ channel: 'sms', subscribed: false },
{ channel: 'whatsapp', subscribed: false },
{ channel: 'web_push', subscribed: true }
]
}identify(userId, traits) liga o reachyID a um identificador externo (CRM, ERP, login) sem criar contato. userId é uma string; traits é um objeto livre guardado localmente e enviado no evento identify.
MySDK.identify('crm-42', { plan: 'pro', company: 'Acme' });
// or, via queue:
reachy.identify.push('crm-42', { plan: 'pro' });getReachyID() retorna o ID atual; getUserData() retorna o que o SDK guardou do contato; isUserRegistered() diz se já houve cadastro neste navegador (útil para esconder o formulário).clearUserData() apaga os dados locais e mantém o reachyID; clearUserIdentity() apaga tudo, inclusive o ID. Use em logout de áreas restritas e em pedidos de esquecimento.Eventos são o registro do que o visitante faz. Alguns o SDK envia sozinho; os do seu negócio você envia com uma linha. Todos entram na linha do tempo do contato e podem filtrar Públicos e disparar Jornadas.
MySDK.trackEvent('Form Completed', { source: 'quiz', plan: 'basic' });
// or, via queue:
reachy.event.push('Form Completed', { source: 'quiz' });'Form Completed' e 'form_completed' são eventos diferentes.snake_case e os mesmos nomes usados em properties do contato.Exemplo: evento nomeado em um botão. O evento automático click já registra qualquer clique, mas um evento com nome próprio é melhor como gatilho de Jornada ou filtro de Público, porque não depende do seletor do elemento. Dê um id ao botão e use um listener no document, que sobrevive a re-renderizações:
<script>
document.addEventListener('click', function (e) {
var target = e.target.closest('#cta-main');
if (!target) return;
reachy.event.push('CTA Clicked', {
button: 'cta-main',
text: (target.textContent || '').trim(),
page: location.pathname
});
});
</script>| Evento | Quando é enviado | Dados | Opção |
|---|---|---|---|
page_enter | A cada página aberta, inclusive troca de rota em SPA | url, domain, path, title, referrer | trackPageViews (ligada) |
UTM Visited | Página aberta com parâmetros UTM na URL | utm_source, utm_medium, utm_campaign, utm_term, utm_content | trackUtmVisited (ligada) |
click | Clique em qualquer elemento | element (tag, id, text, href, type), position | trackClicks (ligada) |
outbound_click | Clique em link para outro domínio | url, text, target, rel, link, current | trackOutboundLinks (ligada) |
time_on_page | Ao sair da página | total_time, time_since_last_activity, is_active | trackTimeOnPage (ligada) |
user_idle / user_activity_resumed | 30 minutos sem atividade / retorno | tempo parado | activityTracking (ligada) |
page_leave | Ao sair da página | url, domain, path, title | trackPageLeave (desligada) |
scroll_depth | Ao atingir 25, 50, 75 e 100% da página | percentual atingido | trackScrollDepth (desligada) |
page_hidden / page_visible | Troca de aba e retorno | timestamp | trackVisibility (desligada) |
create_contact, identify | Chamadas de createContact e identify | dados do contato / userId e traits | sempre |
web_push_subscribed, web_push_permission_denied, web_push_unsubscribed, web_push_sync | Ciclo do web push | inscrição e permissão | sempre |
Sites com muito tráfego costumam desligar trackClicks para manter a linha do tempo enxuta. Formulários: envios e mudanças de campo contam como atividade do visitante e mantêm a sessão viva; para registrar as respostas, envie um evento customizado no submit, como no Início rápido.
Sete métodos com schema padronizado, em MySDK.ecommerce. Cada um envia um evento com nome fixo, o que permite relatórios e jornadas prontas para loja.
MySDK.ecommerce.productViewed({ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, currency: 'BRL', category: 'clothing' });
MySDK.ecommerce.addedToCart({ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 });
MySDK.ecommerce.checkoutStarted({ order_id: 'ORD-789', total: 159.8, payment_method: 'pix', items: [{ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 }] });
MySDK.ecommerce.orderCompleted({ order_id: 'ORD-789', total: 159.8, shipping: 15, tax: 0, currency: 'BRL', payment_method: 'pix', coupon: 'WELCOME10', items: [{ product_id: 'SKU-1001', name: 'Black T-shirt', price: 79.9, quantity: 2 }] });| Método | Evento | Campos |
|---|---|---|
productViewed | product_viewed | product_id, name, price, currency, category, brand, variant, list_name, position |
addedToCart | product_added_to_cart | product_id, name, price, quantity, currency |
removedFromCart | product_removed_from_cart | product_id, name, price, quantity |
cartViewed | cart_viewed | cart_id, items, total, currency |
checkoutStarted | checkout_started | order_id, total, payment_method, items |
orderCompleted | order_completed | order_id, total, shipping, tax, currency, payment_method, coupon, items |
couponApplied | coupon_applied | coupon, discount |
currency assume BRL quando omitida; items é uma lista de { product_id, name, price, quantity }.
Uma sessão agrupa a visita de um mesmo visitante. Ela dura 30 minutos e é estendida automaticamente enquanto houver atividade. Uma sessão nova começa em três situações:
utm_source entre uma página e outra, ou seja, o visitante voltou por outra origem.A sessão é guardada no navegador e sobrevive a recarregamentos e trocas de aba. Com cookieDomain, vale para todos os subdomínios. Todo evento leva o bloco session com id, createdAt, expires e isNew (verdadeiro só no primeiro evento da sessão).
MySDK.renewSession() força uma sessão nova e MySDK.clearSession() encerra a atual. Via fila: reachy.session.push('renew') e reachy.session.push('clear').
O SDK observa mouse, teclado, rolagem e toque. Após 30 minutos sem nada (idleTimeout) envia user_idle; quando o visitante volta, user_activity_resumed. Ao sair da página envia time_on_page com o tempo total e se o visitante estava ativo nos últimos 30 segundos.
utm_source, utm_medium, utm_campaign, utm_term e utm_content da URL e os guarda para a visita inteira. As páginas seguintes continuam atribuídas à mesma origem mesmo sem parâmetros na URL.utms com esses valores.UTM Visited. Use-o para medir origem de tráfego em Públicos e para disparar Jornadas por campanha.properties no createContact.Com web push, o Reachy envia notificações ao navegador do visitante mesmo com o site fechado. O SDK cuida do pedido de permissão, da inscrição e do vínculo com o contato.
reachy-sw.js, baixado de https://sdk.reachy.io/reachy-sw.js, hospedado na raiz do seu site, em /reachy-sw.js. O navegador exige que o service worker venha do próprio domínio. Outro caminho pode ser indicado em pushServiceWorkerPath.const result = await MySDK.push.requestPermission();
if (result.status === 'subscribed') {
// browser subscribed and linked to the visitor
}
// or, via queue:
reachy.webpush.push('requestPermission');O que acontece:
pushPromptCooldownDays do snippet, senão o valor do painel, senão 3, 7 e 30 dias a cada dispensa.reachyID.Quando o seu próprio site já pergunta ao visitante (uma etapa do formulário, por exemplo), pule o aviso do Reachy com requestPermission({ skipSoftPrompt: true }).
Estados retornados em result.status:
| Status | Significado |
|---|---|
subscribed | Inscrito. result.subscription traz os dados da inscrição. |
default | O visitante fechou o pedido nativo sem responder. |
denied | Permissão negada, agora ou anteriormente. |
soft_prompt_dismissed | Dispensou o aviso do Reachy. |
soft_prompt_cooldown | Aviso em intervalo após dispensa anterior. |
unsupported | Navegador sem suporte. |
no_passcode, config_unavailable | Passcode ausente ou canal não configurado no projeto. |
A chamada nunca lança exceção; trate pelo status.
Se o canal no painel tiver exibição automática ligada, com condição de páginas vistas ou segundos na página, o SDK mostra o soft prompt sozinho, uma vez por carregamento, sem código no site. pushAutoShow: false no snippet desliga esse comportamento.
pushAutoResync) para manter o vínculo com o contato.MySDK.push.unsubscribe() cancela a inscrição; push.getSubscription() e push.getPermission() consultam o estado; push.isSupported() responde se o navegador suporta.communication_preferences com web_push ativo no createContact.web_push_subscribed, web_push_permission_denied, web_push_unsubscribed e web_push_sync. Servem como gatilho de Jornada, por exemplo uma notificação de boas-vindas logo após a inscrição.
O service worker recebe a notificação (título, texto, ícone, imagem, botões e URL definidos na campanha), exibe no sistema do visitante e, no clique, abre a URL e registra o clique no Reachy. Não é preciso editar o arquivo.
Quando o visitante passa de um site para outro, o navegador não compartilha cookies nem localStorage entre domínios diferentes, e o segundo site o veria como um visitante novo. O SDK resolve isso de duas formas, conforme o caso.
| Caso | Solução |
|---|---|
Subdomínios do mesmo domínio (app.seusite.com e blog.seusite.com) | cookieDomain |
Domínios diferentes (seusite.com e outrosite.com) | crossDomainLinker |
Configure cookieDomain: '.seusite.com' nos dois sites. O cookie passa a ser a fonte da identidade e da sessão, e nada muda nas URLs.
window.reachy.queue.push({ type: 'config', data: { passcode: 'YOUR_PASSCODE', cookieDomain: '.yoursite.com' } });O site de origem acrescenta três parâmetros à URL de destino (_rcy_uid, _rcy_sid, _rcy_ts). O site de destino lê os parâmetros, confere o prazo, adota a mesma identidade e sessão e limpa a URL sem recarregar a página. É o mesmo mecanismo do parâmetro _gl do Google Analytics.
Configure nos dois sites, com o mesmo paramPrefix:
window.reachy.queue.push({ type: 'config', data: {
passcode: 'YOUR_PASSCODE',
crossDomainLinker: {
hosts: ['othersite.com'], // domains this site hands the identity to
paramPrefix: '_rcy',
ttlMs: 120000
}
}});| Opção | Padrão | Descrição |
|---|---|---|
hosts | [] | Domínios para os quais este site decora links. O match é por sufixo: outrosite.com cobre www.outrosite.com. Vazio desliga a decoração. |
paramPrefix | _rcy | Prefixo dos parâmetros. Origem e destino precisam usar o mesmo. |
ttlMs | 120000 | Validade dos parâmetros em milissegundos (2 minutos). |
enabled | true | Desliga tudo quando false. |
stripUrl | true | Remove os parâmetros da URL após a leitura. |
Como usar
<a href> e formulários para os domínios em hosts são decorados automaticamente no clique.MySDK.decorate(url) antes de navegar. A função devolve a URL com os parâmetros quando o destino está em hosts, ou a URL original caso contrário, e nunca lança exceção.window.location.href = MySDK.decorate('https://othersite.com/thank-you');Limites: os parâmetros valem por 2 minutos; o vínculo acontece só na navegação iniciada no site de origem (quem digita a URL do destino chega como visitante novo); o linker mantém o mesmo visitante, mas não substitui o cadastro.
reachyID, sessão, UTMs, URL, referrer.createContact, trackEvent ou identify de propósito.password, pass, token, secret, credit, card, cvv, email, phone, cpf, cnpj ou ssn. A lista pode ser estendida em deniedFieldPatterns.Para sites que exigem aceite de cookies antes de qualquer rastreio, inicie o SDK com respectPrivacy: true. Nesse modo os eventos automáticos ficam bloqueados até o visitante consentir, e o sinal Do Not Track do navegador é respeitado. Chamadas feitas pelo seu código (createContact, trackEvent) continuam funcionando, porque é o site quem decide chamá-las.
// in the snippet
window.reachy.queue.push({ type: 'config', data: { passcode: 'YOUR_PASSCODE', respectPrivacy: true } });
// when the visitor accepts in the cookie banner
MySDK.updateConfig({ respectPrivacy: false });
// if the visitor declines, also turn off automatic capture
MySDK.setAutoTracking(false);MySDK.isTrackingPermitted() informa se a captura automática está liberada no momento.
MySDK.clearUserIdentity() apaga reachyID, dados locais e fingerprint do navegador; MySDK.clearSession() encerra a sessão. A exclusão do contato no Reachy é feita pelo painel.
É um assunto separado do rastreio: is_subscribed e communication_preferences no createContact dizem ao Reachy se o contato pode receber e-mail, SMS, WhatsApp e web push. Envie true apenas com opt-in real do visitante, e false quando ele não marcou o aceite.
Os e-mails enviados pelo Reachy levam um link de descadastro. Por padrão ele abre uma página do Reachy; com o SDK você pode ter a página no seu próprio site, com a sua marca. O link traz um token (?u=token) ou o ID do contato (?rid=id), e o SDK resolve e confirma o descadastro a partir dele.
MySDK.resolveUnsubscribeFromUrl(). Ela lê os parâmetros e devolve { email_masked }, por exemplo a***@email.com, para a página mostrar "Descadastrar a***@email.com?".MySDK.confirmUnsubscribeFromUrl(). O Reachy atualiza as preferências do contato, registra o evento channel_unsubscribed na linha do tempo e atribui o descadastro à campanha ou jornada que enviou o e-mail.const info = await MySDK.resolveUnsubscribeFromUrl();
if (!info) { showExpiredLink(); return; }
showQuestion(info.email_masked);
confirmButton.onclick = async () => {
const ok = await MySDK.confirmUnsubscribeFromUrl();
ok ? showSuccess() : showExpiredLink();
};| Método | Parâmetros | Retorno |
|---|---|---|
resolveUnsubscribeFromUrl(options?) | options.tokenParam (padrão u), options.ridParam (padrão rid) | { email_masked } ou null |
confirmUnsubscribeFromUrl(options?) | os mesmos, mais options.campaignParam (padrão campaign) | true em sucesso |
resolveUnsubscribeByToken(token) | token do link | { email_masked } ou null |
unsubscribeByToken(token) | token do link | true em sucesso |
resolveUnsubscribeByReachyId(reachyId) | ID do contato | { email_masked } ou null |
unsubscribeByReachyId(reachyId, campaignId?) | ID do contato e, opcional, a campanha para atribuição | true em sucesso |
O token identifica contato e envio e tem validade, por isso é a forma preferida. Os nomes dos parâmetros são configuráveis para quem já tem uma URL de descadastro com outro formato.
Toda opção entra no objeto data do snippet ou em MySDK.updateConfig(config) a qualquer momento. O que não for informado usa o padrão.
| Grupo | Opção | Padrão | Descrição |
|---|---|---|---|
| Conexão | passcode | vazio | Chave do projeto. Obrigatória; sem ela nada é enviado. |
| Conexão | debug | false | Liga o painel de depuração flutuante. Também liga com ?reachy_debug=true na URL. |
| Conexão | queueEnabled | true | Fila offline com reenvio automático quando a rede falha. |
| Identidade | autoIdentityManagement | true | O SDK cria e persiste o reachyID sozinho. |
| Identidade | cookieDomain | domínio atual | Compartilha identidade e sessão entre subdomínios (.seusite.com). |
| Identidade | crossDomainLinker | desligado | Identidade entre domínios diferentes. Ver Cross-domain. |
| Sessão | sessionTimeout | 30 min | Inatividade que encerra a sessão. |
| Sessão | liveUsersEnabled | true | Envia page_enter e page_leave para a contagem de visitantes ao vivo. |
| Captura automática | autoTracking | true | Liga o grupo inteiro de captura automática. |
| Captura automática | trackPageViews | true | page_enter em cada página, inclusive em SPAs. |
| Captura automática | trackUtmVisited | true | Evento UTM Visited quando a URL tem UTMs. |
| Captura automática | trackClicks | true | Evento click em botões, links e demais elementos. |
| Captura automática | trackOutboundLinks | true | Evento outbound_click ao sair para outro domínio. |
| Captura automática | trackScrollDepth | false | Evento scroll_depth nos limiares de scrollThresholds. |
| Captura automática | scrollThresholds | [25, 50, 75, 100] | Percentuais de rolagem que disparam scroll_depth. |
| Captura automática | trackPageLeave | false | Evento page_leave ao sair da página. |
| Captura automática | trackVisibility | false | Eventos page_hidden e page_visible ao trocar de aba. |
| Captura automática | trackTimeOnPage | true | Evento time_on_page ao sair. |
| Formulários | trackFormSubmits | true | Conta envios de formulário como atividade do visitante. |
| Formulários | trackFormFieldChanges | true | Conta mudanças em campos como atividade do visitante. |
| Formulários | deniedFieldPatterns | password, pass, token, secret, credit, card, cvv, email, phone, cpf, cnpj, ssn | Campos que o SDK ignora ao observar formulários (match por nome, id ou tipo). |
| Atividade | activityTracking | true | Detecção de atividade e inatividade. |
| Atividade | idleTimeout | 30 min | Sem atividade por esse tempo, envia user_idle. |
| Atividade | heartbeatInterval | 5 min | Intervalo do pulso que mantém a sessão viva. |
| Privacidade | respectPrivacy | false | Com true, bloqueia a captura automática até haver consentimento. Ver Privacidade. |
| Web push | pushServiceWorkerPath | /reachy-sw.js | Caminho do service worker no seu site. |
| Web push | pushAutoResync | true | Reenvia a inscrição a cada página para manter o vínculo com o contato. |
| Web push | pushSoftPrompt | true | Mostra o aviso do Reachy antes do pedido nativo. |
| Web push | pushPromptCooldownDays | null | Dias sem repetir o aviso após dispensa. null usa o painel ou o escalonamento 3, 7 e 30 dias; 0 desliga o intervalo. |
| Web push | pushAutoShow | true | Permite a exibição automática do aviso conforme o painel. |
Opções de transporte (batchEvents, batchSize, batchTimeout) existem para cenários específicos combinados com o suporte do Reachy; mantenha os padrões.
Todos os métodos estão em window.MySDK. Os métodos que enviam dados retornam Promise<boolean>: true quando o envio foi feito ou enfileirado, false quando os dados eram inválidos ou o envio foi bloqueado. Nenhum método lança exceção.
createContact(data) cria ou atualiza o contato. Campos em Identidade e contatos.
identify(userId, traits?) vincula o visitante a um ID externo. userId string obrigatória; traits objeto opcional.
getReachyID() retorna o reachyID atual (string).
getUserData() retorna o objeto guardado localmente (email, phone, first_name, is_subscribed, properties, externalUserId...). updateUserData(data) faz merge nesse objeto; use antes do cadastro para manter o histórico anônimo.
getUserInfo() retorna { reachyId, userData, isRegistered, fingerprint }. isUserRegistered() retorna boolean.
setReachyID(id) e generateNewReachyID() controlam o ID manualmente; uso avançado.
clearUserData() apaga os dados locais e mantém o ID. clearUserIdentity() apaga ID, dados e fingerprint.
trackEvent(name, data?) envia um evento customizado. name string; data objeto livre.
ecommerce.productViewed(data), addedToCart(data), removedFromCart(data), cartViewed(data), checkoutStarted(data), orderCompleted(data), couponApplied(data): eventos de loja com schema fixo. Campos em Eventos.
renewSession() força uma sessão nova. clearSession() encerra a atual.
MySDK.push)push.isSupported() retorna boolean. push.getPermission() retorna 'default', 'granted' ou 'denied'.
push.requestPermission(options?) pede a permissão; options.skipSoftPrompt: true pula o aviso do Reachy. Retorna { status, subscription? }; estados em Web push.
push.getSubscription() retorna a inscrição atual ou null. push.unsubscribe() cancela a inscrição.
decorate(url) retorna a URL com os parâmetros de identidade quando o destino está em crossDomainLinker.hosts; caso contrário, a URL original.
resolveUnsubscribeFromUrl(options?), confirmUnsubscribeFromUrl(options?), resolveUnsubscribeByToken(token), unsubscribeByToken(token), resolveUnsubscribeByReachyId(reachyId), unsubscribeByReachyId(reachyId, campaignId?): parâmetros e retornos em Página de descadastro.
updateConfig(config) aplica qualquer opção da Referência de configuração. updateTrackingConfig(config) aplica opções de captura e atividade e reinicia os observadores.
setDebug(bool), setAutoTracking(bool), setActivityTracking(bool), setLiveUsersEnabled(bool): atalhos para as opções correspondentes.
use(fn) registra uma função chamada com os dados do evento antes de cada envio. Ela deve retornar os dados (modificados ou não) ou null para bloquear o envio.
MySDK.use((payload) => {
payload.event.data.site_version = '2.1.0'; // adds a field to every event
return payload;
});
MySDK.use((payload) => {
if (payload.event.data.email?.endsWith('@yourcompany.com')) return null; // skips internal users
return payload;
});isTrackingPermitted() retorna boolean. Ver Privacidade e consentimento.
getInfo() retorna { version, initialized, queueSize, batchBufferSize, session, reachyID, userData, userInfo, autoTracking, activityTracking, trackingStats, utmParams, currentUrl }; em config.passcode aparece [CONFIGURED] ou [NOT SET]. getTrackingStats() retorna contadores de eventos e atividade. clearQueue() descarta a fila offline. destroy() para a captura, remove os observadores e libera a instância.
Antes de o script carregar: window.reachy.queue.push({ type, data }) com config, createContact, trackEvent ({ eventName, eventData }), identify ({ userId, traits }), webpush ({ action, options }), renewSession e clearSession. Depois: reachy.event.push, reachy.login.push, reachy.identify.push, reachy.webpush.push, reachy.session.push, reachy.privacy.push e reachy.config.push executam imediatamente.
Abra qualquer página do site com ?reachy_debug=true no final da URL. Um painel flutuante mostra o reachyID, a sessão atual e cada evento no momento em que é enviado, com os dados. O mesmo efeito vem de debug: true na configuração ou de MySDK.setDebug(true) no console. O painel é a ferramenta de validação: o SDK não imprime logs no console do navegador.
MySDK.getInfo() mostra versão, sessão, reachyID, UTMs, fila pendente e a configuração em uso; config.passcode aparece como [CONFIGURED] quando o passcode foi aplicado.MySDK.getUserData() mostra o que o SDK guardou do contato neste navegador.api-sdk e recarregue a página: deve aparecer uma requisição para a API do SDK com event.name: "page_enter" no corpo da requisição. Se o site navega após o clique, marque Preserve log.Em Contacts, o contato de teste aparece em até 1 minuto com os campos enviados em properties; a aba de atividades lista os eventos na ordem em que chegaram. No construtor de Públicos, aba de comportamento, o evento aparece na lista assim que chega.
| Sintoma | O que conferir |
|---|---|
MySDK is not defined no console | O script não está na página. Veja o código-fonte e procure sdk.reachy.io. Se não aparecer, é cache ou condição do gerenciador de tags. |
getInfo() mostra passcode: "[NOT SET]" | A configuração não foi aplicada. Confira o snippet (window.reachy.queue com type: 'config', dentro do mesmo <script>) ou o updateConfig no onload. |
| Painel mostra os eventos, mas nada aparece no Reachy | O passcode é de outro projeto. Confira o projeto ativo no topo do Reachy. |
| Nenhuma requisição em Network | Passcode ausente, aba dentro de um editor visual, ou bloqueador de anúncios. Teste em aba anônima sem extensões. |
| Site com Content Security Policy | Libere script-src https://sdk.reachy.io e connect-src https://api-sdk.reachy.io https://api.reachy.io. |
| Evento chegou anônimo, sem contato | O evento saiu antes do createContact. Cadastre primeiro e envie o evento depois. |
| Contato duplicado | Dois e-mails diferentes no mesmo navegador geram IDs diferentes, por desenho. Para manter o histórico, use updateUserData({ email }) antes do cadastro. |
| Funciona logado, não em aba anônima | Cache servindo HTML antigo. Limpe o cache do plugin e da CDN. |
reachy.ecommerce is undefined | Os métodos de e-commerce ficam em MySDK.ecommerce, depois de MySDK.initialized. |
Web push retorna config_unavailable | O canal Web Push não está configurado no projeto. |
Web push retorna unsupported | Navegador sem suporte, ou site fora de HTTPS. |
https://sdk.reachy.io/sdk.jsMySDK.getInfo() mostra [CONFIGURED] em aba anônimapage_enter aparece em Network ao recarregarproperties e is_subscribed corretostrackClicks, trackScrollDepth) conforme o volume do sitereachy-sw.js na raiz do site e canal configurado no projetorespectPrivacy e a liberação no aceite| Navegador | Versão mínima | Suporte |
|---|---|---|
| Chrome | 60 | Completo |
| Firefox | 55 | Completo |
| Safari | 12 | Completo |
| Edge | 79 | Completo |
| Internet Explorer | 11 | Limitado: sem web push; envio pelos meios alternativos |
Web push depende de Service Worker e da API Push: Chrome, Firefox, Edge e Safari 16.4 ou superior; no iOS, apenas com o site adicionado à tela inicial. MySDK.push.isSupported() responde em tempo de execução.
A versão atual é a 1.1.0, disponível em https://sdk.reachy.io/sdk.js. O número aparece em MySDK.getInfo().version e no campo sdkVersion de toda requisição. Atualizações são publicadas na mesma URL e mantêm compatibilidade com o snippet e com os métodos desta referência.
| Versão | Destaques |
|---|---|
| 1.1.0 | Web push com soft prompt e exibição automática; cross-domain linker; helpers de descadastro; eventos de e-commerce; fila de comandos window.reachy.queue |