Skip to main content
O script do banner é a integração principal do ConsentFly: uma linha de HTML que exibe o banner de cookies, coleta a decisão do visitante e a envia para a API. Esta página é a referência completa — instalação, configuração, comportamento e resolução de problemas.

Instalação

Adicione o snippet antes de </body>, substituindo SITE_ID pelo site_id do seu site (painel → Sites):
data-site-id é o único atributo obrigatório. Sem ele, o script não faz nada — nenhum banner, nenhuma chamada de rede.

Como funciona

Em cada carregamento de página, o script:
  1. Deriva a base da API da própria URL do script (document.currentScript.src, com fallback para uma busca por script[src*="/api/v1/script.js"]). Se o script foi carregado de https://www.consentfly.com.br/..., todas as chamadas vão para https://www.consentfly.com.br/api/v1.
  2. Reenvia silenciosamente qualquer consentimento pendente de uma visita anterior em que a rede falhou (ver Fila offline).
  3. Busca a configuração do site em GET /api/v1/public/site/{siteId} — textos, link da política, policy_version, geo_enabled e o script_token.
  4. Decide se exibe o banner (ver Quando o banner não aparece).
  5. Ao clicar em Aceitar, Recusar ou salvar preferências no modal, grava a decisão em localStorage primeiro, fecha o banner imediatamente e envia POST /api/v1/public/consent em segundo plano com o header X-Site-Token.
Armadilha do script “proxiado”. Como a base da API vem do src do script, um cliente que serve o script pelo próprio domínio (proxy/CDN próprio) recebe um banner que chama https://seudominio.com/api/v1/... — e falha, a menos que o proxy repasse também as rotas /api/v1/public/*. Este é o erro de integração mais comum. Se não for repassar a API inteira, sirva o script diretamente de www.consentfly.com.br.
Timeouts de rede são de 6 segundos por requisição. Nenhuma falha de rede bloqueia a UI: o banner nunca prende o visitante esperando o backend.

Atributos de configuração

Todos opcionais, exceto data-site-id. Atributos de texto têm precedência sobre a configuração cadastrada no painel; os de política só são usados como fallback quando a busca de configuração falha.

Categorias de consentimento

O modal “Configurar cookies” expõe três categorias:
  • Aceitar envia accepted: true com analytics: true, marketing: true.
  • Recusar envia accepted: false com ambas false.
  • Salvar preferências (modal) envia accepted: true com os toggles escolhidos.

Armazenamento no navegador

O script usa localStoragenenhum cookie é criado — com fallback em memória quando localStorage está indisponível (modo privado restrito, etc.). Também não faz nenhuma requisição a terceiros: fala apenas com a origem de onde foi servido.
O prefixo haldenhub- é permanente — chaves de armazenamento, ids de DOM (haldenhub-banner, haldenhub-modal) e classes CSS (haldenhub-button, …) mantêm esse nome para que decisões já gravadas nos navegadores dos visitantes continuem válidas. Não trate como erro nem espere renomeação.

Quando o banner não aparece

O script encerra sem montar nada quando qualquer condição abaixo vale:
  1. Já existe consentimento válido: haldenhub-consent guarda uma decisão para o mesmo site_id e a mesma policy_version. Publicar uma nova versão da política reexibe o banner para todos.
  2. show_banner: false na configuração do site (hoje o servidor sempre envia true; o campo existe para supressão futura sem nova versão do script).
  3. Geofencing ativo e visitante fora da região (abaixo).
  4. data-site-id ausente ou o script já foi inicializado na página (guarda window.haldenhubBannerInitialized contra inclusão dupla).

Geofencing

Chave opcional por site (padrão desligado) que restringe a exibição do banner a visitantes da UE/EEE + Reino Unido + Suíça. Pensada para clientes que operam fora do Brasil e só querem o banner onde ele é expectativa legal. A decisão roda no navegador, não no servidor: o script compara Intl.DateTimeFormat().resolvedOptions().timeZone com uma lista de zonas IANA dessas jurisdições. Fora da lista, o script encerra — sem DOM, sem chamadas. Falha aberta, de propósito: zona desconhecida, navegador sem Intl ou qualquer exceção resultam em banner exibido. Mostrar o banner a quem não precisava é um incômodo; escondê-lo de quem precisava é falha de compliance — só um dos dois é aceitável.
Geofencing é uma decisão de exibição, não um controle de acesso. Um visitante pode mentir sobre o próprio fuso horário — a única coisa que ele muda com isso é ver ou não o banner. Territórios ultramarinos com fuso próprio (Guiana Francesa, Reunião) ficam fora da lista e caem no lado seguro: banner exibido. Para sites com público brasileiro, mantenha a chave desligada — a LGPD vale para todo visitante, independentemente da origem.

Personalização visual

O script injeta um CSS próprio (cores fixas, botão de aceite em azul escuro) e não há atributo de tema ou cor de destaque. A personalização é feita por CSS do seu site, sobrescrevendo as classes haldenhub-* — que são estáveis (ver nota sobre o prefixo acima):
O banner usa z-index: 2147483647 e o modal fica logo abaixo, para nunca serem cobertos pelo layout do site.

Token do site e rotação

Cada site tem um script_token que autentica o POST /public/consent. O token viaja no header X-Site-Token (o fallback via navigator.sendBeacon usa o parâmetro ?script_token=). Ele é entregue ao navegador dentro do payload de GET /public/site/{siteId} — ou seja, não é um segredo: é uma chave por site que permite revogar um embed vazado sem invalidar os demais sites.
  • A verificação falha fechada: token inválido ou ausente retorna 401 com código unauthorized (“Invalid or missing script token”). Nenhum consentimento é gravado.
  • Rotacione com POST /api/v1/sites/{siteId}/rotate-script-token (autenticado) ou pelo painel. A rotação invalida o cache da configuração pública; visitantes recebem o token novo no próximo carregamento de página.

Fila offline

A decisão do visitante é gravada localmente antes de qualquer chamada de rede, então o clique sempre é honrado mesmo se o backend, a rede ou uma CSP bloquearem a requisição:
  1. O payload é salvo em haldenhub-consent-pending e o banner fecha imediatamente.
  2. O envio acontece em segundo plano; se o fetch falhar, o script tenta navigator.sendBeacon como último recurso.
  3. Sucesso limpa a fila; falha mantém o payload, que é reenviado silenciosamente no próximo carregamento de página.
Consequência para auditoria: uma decisão pode chegar ao banco minutos ou dias depois de tomada — o created_at do registro é o momento de recepção no servidor, não o do clique.

Limites e caching

  • POST /public/consent tem corpo limitado a 64 KiB (413 acima disso) e rate limit de 30 req/min por cliente e 600 req/min por site (429 com too_many_requests).
  • O script.js é servido com Cache-Control: public, max-age=300 e a configuração do site é cacheada no servidor. Mudanças de texto/política feitas no painel podem levar até ~5 minutos para aparecer nos visitantes.
  • O IP bruto do visitante nunca é persistido — o servidor resolve país/região e descarta o endereço antes da gravação.

Troubleshooting

O banner não aparece

  • Consentimento já registrado neste navegador. Limpe haldenhub-consent (e opcionalmente haldenhub-consent-id) no localStorage e recarregue. É o motivo mais comum durante testes.
  • data-site-id ausente ou vazio na tag do script.
  • site_id inexistente: GET /public/site/{siteId} retorna 404 e o script cai no modo fallback — nesse caso o banner ainda aparece com os textos padrão, mas os envios não serão aceitos. Confira o Network do DevTools.
  • Geofencing ligado e o fuso horário do navegador está fora da UE/EEE/UK/CH. Desligue a chave no painel ou teste com o fuso de um país coberto.
  • Script incluído duas vezes: só a primeira inicialização roda (window.haldenhubBannerInitialized).
  • Bloqueio por CSP ou adblock: verifique se script-src permite www.consentfly.com.br e se não há extensão bloqueando a requisição.

401 unauthorized no POST /public/consent

  • Token rotacionado com página antiga aberta: abas carregadas antes da rotação seguram o token velho. O payload fica na fila offline e é reenviado — mas continuará falhando até o visitante recarregar a página e receber o token novo.
  • Requisição manual sem X-Site-Token: o endpoint exige o token em toda chamada (header, ?script_token= ou campo script_token no corpo).
  • Fallback ativo: se a busca de configuração falhou, o script monta o banner sem token e os envios retornam 401 até a configuração voltar a carregar.

Erros de CORS

  • Os endpoints públicos aceitam qualquer origem, sem credenciais — o script chama com credentials: "omit". Se você vê erro de CORS, quase sempre a causa é a armadilha do proxy: o script foi servido de outro domínio e está chamando /api/v1 nesse domínio, que não existe ou responde sem os headers de CORS.
  • Confira também connect-src na sua CSP: ele precisa permitir https://www.consentfly.com.br.

Dúvidas? suporte@consentfly.com.br