Atribuição — Visão geral
A atribuição é a coluna vertebral do tracking de marketing. Decide qual canal recebe o crédito por uma conversão e alimenta os relatórios de BI. Esta página explica como o front-end Cactus captura, persiste e propaga os dados de atribuição.
Princípio central: last-touch
Cada vez que o usuário entra em uma URL com qualquer parâmetro de tracking, o sistema sobrescreve seletivamente os dados antigos: cada campo que veio na URL nova vence o anterior; campos ausentes na URL nova são preservados.
Mudar essa política altera silenciosamente todos os dashboards de BI (calibrados em last-touch desde o legado Vue). Qualquer discussão de first-touch precisa de alinhamento com BI antes.
Exemplo prático de sobrescrita
Usuário entra em:
https://vera.bet.br/?utm_source=facebook&utm_campaign=black-friday&ref=AFIL1
Cookie cookie_tracking fica:
{
"utm_source": "facebook",
"utm_campaign": "black-friday",
"affiliation_code": "AFIL1"
}
Mais tarde, mesmo usuário clica em:
https://vera.bet.br/?utm_campaign=cyber-monday&utm_medium=cpc
Cookie agora:
{
"utm_source": "facebook", // ← preservado (não veio na URL nova)
"utm_campaign": "cyber-monday", // ← sobrescrito
"utm_medium": "cpc", // ← novo, adicionado
"affiliation_code": "AFIL1" // ← preservado
}
:::warning Atenção operacional
Se uma campanha NÃO passar utm_source, ela herda silenciosamente o utm_source da campanha anterior. Sempre passe o set completo de UTMs em cada link de campanha.
:::
As 3 camadas de captura
A captura acontece em três pontos coordenados pra garantir que nenhum redirect server-side perca atribuição:
Camada 1 — Server loader (app/root.tsx)
Roda em todo request, antes de qualquer redirect. Lê os params da URL, faz merge com o cookie atual e emite Set-Cookie na response.
Por que server-side? A versão anterior só fazia captura client-side em useEffect. Cenário que falha:
- User clica em link de afiliado:
/?utm_source=afiliado&ref=AFIL1 - Algum loader filho inspeciona
?ref=e fazredirect(302)pra outra rota - Browser segue o 302; URL final já não tem UTMs
- Client hidrata;
useEffectmonta maswindow.location.searchestá limpo - Cookie nunca é escrito; signup/deposit submete sem atribuição
Captura no root loader resolve isso: o Set-Cookie é emitido no mesmo response que carrega o redirect — quando o browser hidrata na rota destino, o cookie já existe.
Camada 2 — Client component (TrackingCapture.tsx)
Roda em toda navegação SPA (via useLocation()). Re-aplica a captura quando a URL muda sem full reload — replica o middleware global do Nuxt legado.
Também responsável por:
- Detecção de PWA (
matchMedia('(display-mode: standalone)')) → preencheapp_source: "pwa"quando ausente - Captura de
document.referrer(one-shot, persiste emcookie_referrer) - Auto-open de modal quando
?ref=CODEaparece (register pra deslogado, deposit pra logado)
Camada 3 — Submit final (RegisterModal + DepositModal)
No submit do form, lê o cookie e injeta os campos no body do POST pro BFF. Detalhes do payload em UTMs.
Política de sanitização
Cada valor passa por sanitizeTrackingValue() antes de persistir:
- HTML entities (
<,>,",',`) — strippadas - Substrings perigosas (
document,createElement,appendChild) — strippadas - Tags inline (
<script>...</script>,<img ... src=...>) — strippadas - Placeholders não-substituídos (
{fbclid},{{campaign.id}},__CLICKID__,__CAMPAIGN_ID__) — descartados completamente - Valores acima de 500 chars — truncados
- PII conhecida (
user_phone,user_email,user_name,pixel,currency) — nunca capturada, mesmo se a URL trouxer
Evita que UTMs maliciosas/quebradas cheguem em dashboards de analytics.
Cap de chaves no cookie
Cookie cookie_tracking tem cap de 20 chaves (proteção contra abuse de URL stuffing). Quando o cap é atingido, chaves canonical são preservadas e extras são descartadas:
Sempre preservadas (canonical priority):
utm_source,utm_campaign,utm_medium,utm_content,srcmedia_source,media_clidaffiliation_code,subid,app_source- Todos os clicked-IDs (
gclid,fbclid,ttclid, etc)
Descartadas primeiro: utm_* extras (custom tags como utm_oferta, utm_term, utm_creative).
Pra continuar
- Quais parâmetros são capturados → UTMs
- Clicked-IDs (gclid, fbclid, etc) → Clicked-IDs
- Affiliate code e Clever → Affiliate
- Onde os dados ficam armazenados → Storage → Cookies
- Como testar uma campanha de ponta a ponta → Operação → Testar campanha