Como Adicionar Analytics Focado em Privacidade a uma App SvelteKit
O SvelteKit 2 intercepta a navegação client-side de forma diferente dos outros frameworks. Este é o padrão correto para rastrear mudanças de rota sem cookies ou banners de consentimento.
O SvelteKit 2 quebra integrações de analytics que apoiam a medição no ciclo de vida da página. Uma tag <script> simples dispara uma única vez, no primeiro carregamento do documento, e nunca mais — então toda navegação client-side depois disso fica invisível. O tracker do Monoid evita isso observando a History API em vez do ciclo de vida da página.
Por que uma tag script simples não basta
Uma tag <script> em <svelte:head> é executada uma vez por carregamento de documento. O router do SvelteKit 2 troca o conteúdo no lugar sem descarregar o documento, então nada a re-executa. Qualquer tracker cujo único gatilho seja DOMContentLoaded ou load registra a rota de entrada e depois silencia.
Esta é a causa raiz do problema amplamente relatado em que o Google Analytics GA4 registra apenas o primeiro pageview no carregamento inicial em aplicações SvelteKit 2.
Detectar a própria navegação é a resposta, e isso não exige uma integração específica para SvelteKit. O router client-side do SvelteKit atualiza a URL chamando history.pushState, então um tracker que aplica patch em history.pushState observa cada mudança de rota client-side sem assinar $app/navigation nem qualquer hook do framework.
A abordagem correta
Adicione o script do tracker do Monoid uma vez no seu +layout.svelte raiz usando <svelte:head>:
<svelte:head>
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id="SEU_SITE_ID"
></script>
</svelte:head>
O listener de DOMContentLoaded do tracker cobre o carregamento inicial da página. Para navegações client-side subsequentes, seu patch em history.pushState roda imediatamente após o SvelteKit atualizar a URL, então ele lê o novo location.pathname e envia um pageview por mudança de rota.
Uma ressalva importante: o patch cobre pushState, não popstate. Os botões Voltar e Avançar mudam a rota sem chamar pushState, então atualmente não produzem um novo pageview.
Para verificar, abra a aba de Rede no DevTools e observe as requisições POST para /collect. Você deve ver uma por mudança de rota.
Separar o tráfego de staging
Projetos SvelteKit geralmente rodam em localhost durante o desenvolvimento. Registre um site separado e vincule seu site_id a uma variável de ambiente para que o tráfego de desenvolvimento nunca contamine as métricas de produção:
<script>
const siteId = import.meta.env.VITE_MONOID_SITE_ID
</script>
<svelte:head>
{#if siteId}
<script
async
src="https://api.monoid.website/tracker.min.js"
data-site-id={siteId}
></script>
{/if}
</svelte:head>
Defina VITE_MONOID_SITE_ID no .env.local para desenvolvimento (ou deixe sem definir para suprimir o tracking) e no ambiente de deploy para produção. O bloco {#if siteId} garante que o script do tracker nunca seja injetado quando a variável não estiver definida.
O que você não precisa
Sem banner de consentimento de cookies. Sem atualização de política de cookies. Sem verificação de navigator.cookieEnabled. O endpoint de coleta deriva um hash de visitante diário a partir do endereço IP, do User-Agent, de um segredo do lado do servidor e da data atual:
visitor_hash = SHA-256(IP + UA + SALT_SECRET + YYYY-MM-DD)
O hash é redefinido a cada 24 horas e não pode ser revertido para recuperar o IP ou o User-Agent. Nada é armazenado no dispositivo do visitante. Isso significa que a integração não aciona os requisitos de consentimento da ePrivacy ou da PECR — não há nada sobre o que consentir.
Verificando no dashboard
Após o deploy, abra seu dashboard de analytics e navegue entre várias rotas no seu site em produção. Cada navegação deve produzir uma nova entrada de pageview com o caminho correto. Se você ver apenas uma entrada independentemente da navegação, verifique se o script está carregado no layout raiz e se VITE_MONOID_SITE_ID está configurado no ambiente de produção.
O adaptador SvelteKit que você usa (Cloudflare, Vercel, Node, estático) não afeta a coleta de analytics, já que o tracking ocorre inteiramente no navegador após a hidratação.
Comments
Loading comments…