Documentação · Navegador
Documentação
SDK de navegador
fg-tracker-browser: erros, breadcrumbs, fetch ligado à API e pageviews, com a chave pública e os domínios permitidos.
Conferido com o código e os pacotes publicados em 2026-10-16
O fg-tracker-browser (0.4.0) roda no navegador, sem dependências (cerca de 7 KB com gzip). Ele não substitui o SDK Node: o front usa este pacote e a chave pública; o servidor usa o SDK Node e a chave de servidor.
O que é capturado
| Captura | Padrão | Observação |
|---|---|---|
Erros não tratados e unhandledrejection | ligado | Cada erro vira um trace com span browser, a página e os últimos breadcrumbs. |
| Breadcrumbs (cliques, navegação, console.warn/error, fetch) | ligado | Os 30 últimos vão junto com o erro. |
Traces de fetch | desligado (tracesSampleRate: 0) | Com taxa > 0, o fetch vira trace e leva traceparent para a sua API. |
| Pageviews e visitantes anônimos | desligado | analytics: true. |
| XHR (axios), Web Vitals, tempos de carregamento | não suportado | Chamadas por XMLHttpRequest não geram breadcrumb nem trace. |
Chave pública, nunca a de servidor
O pacote não confere o prefixo. Com fgsk_, além de expor o segredo, o envio falha: os domínios permitidos são procurados pela chave pública, então o CORS recusa a origem, e o sendBeacon recebe 401 SERVER_KEY_IN_URL. No modo restrito, a chave pública continua enviando tudo o que este pacote produz.
Domínios permitidos (CORS)
O navegador só deixa o SDK enviar se a origem do site estiver cadastrada no projeto. Em Configurações → Geral → Domínios permitidos, acrescente cada origem, com protocolo e sem caminho:
https://www.suaempresa.com.br(exata) ouhttps://*.suaempresa.com.br(subdomínios; não inclui o domínio sem prefixo).http://só paralocalhoste127.0.0.1, com a porta:http://localhost:5173.- Até 100 origens. A mudança leva até 1 minuto para valer.
Sem a origem, o console do navegador mostra um erro de CORS em /v1/ingest. O CORS protege a leitura da resposta, não os dados: quem tem a chave pública consegue enviar eventos de navegador ao projeto.
Instalação com bundler
O pacote é só ESM; funciona com Vite, webpack, esbuild, Rollup e o bundler do Next.js.
npm install fg-tracker-browser# .env do front (Vite): só a chave pública
VITE_FG_TRACKER_PUBLIC_KEY=stk_<chave_publica_do_projeto>
VITE_FG_TRACKER_URL=https://tracker-api.fortground.com.brimport { init } from 'fg-tracker-browser';
export const tracker = init({
apiKey: import.meta.env.VITE_FG_TRACKER_PUBLIC_KEY, // stk_… (chave pública)
endpoint: import.meta.env.VITE_FG_TRACKER_URL, // https://tracker-api.fortground.com.br
serviceName: 'checkout-web',
environment: 'development',
release: import.meta.env.VITE_RELEASE, // a mesma dos source maps
});
tracker.setUser({ id: '42' });Chame init uma vez, o mais cedo possível no carregamento da página. O endpoint é obrigatório (sem ele, init lança erro). Erros capturados à mão: tracker.captureException(err); mensagens: tracker.captureMessage('texto', 'info').
Teste rápido sem bundler
Para ver um erro do navegador chegar ao painel em dois minutos. Salve como index.html, cadastre http://localhost:5173 nos domínios permitidos e sirva a pasta:
<!doctype html>
<html lang="pt-BR">
<body>
<button id="erro">Gerar erro de teste</button>
<script type="module">
import { init } from 'https://cdn.jsdelivr.net/npm/fg-tracker-browser@0.4.0/dist/index.js';
const tracker = init({
apiKey: 'stk_<chave_publica_do_projeto>',
endpoint: 'https://tracker-api.fortground.com.br',
serviceName: 'checkout-web',
environment: 'development',
debug: true,
});
document.getElementById('erro').addEventListener('click', () => {
tracker.captureException(new Error('erro de teste do navegador'));
tracker.flush();
});
</script>
</body>
</html>npx serve -l 5173 .Abra http://localhost:5173, clique no botão e veja em Traces com o filtro Raiz: Todas (o padrão HTTP não mostra traces que começam no navegador). A issue aparece em Issues. Em produção, prefira o pacote instalado pelo bundler a um CDN.
Next.js (App Router)
O pacote precisa rodar no cliente: crie um componente com 'use client' e inicialize num useEffect. Renderize-o uma vez no layout raiz.
// app/fg-tracker.tsx
'use client';
import { useEffect } from 'react';
import { init } from 'fg-tracker-browser';
export function FgTracker() {
useEffect(() => {
const tracker = init({
apiKey: process.env.NEXT_PUBLIC_FG_TRACKER_PUBLIC_KEY!, // stk_… (pública)
endpoint: process.env.NEXT_PUBLIC_FG_TRACKER_URL!,
serviceName: 'checkout-web',
environment: process.env.NEXT_PUBLIC_APP_ENV,
});
return () => tracker.close();
}, []);
return null;
}
// app/layout.tsx: renderize <FgTracker /> dentro do <body># .env.local do Next.js
NEXT_PUBLIC_FG_TRACKER_PUBLIC_KEY=stk_<chave_publica_do_projeto>
NEXT_PUBLIC_FG_TRACKER_URL=https://tracker-api.fortground.com.br
# A chave de servidor fica SEM o prefixo NEXT_PUBLIC_ (só o código do servidor lê):
FG_TRACKER_KEY=fgsk_<chave_de_servidor>Os route handlers do mesmo app usam o SDK Node com FG_TRACKER_KEY, lida só no servidor. Confira depois do build que nenhum arquivo em .next/static contém fgsk_: grep -r fgsk_ .next/static não deve achar nada.
Ligar o front ao trace da API
init({
// ...
tracesSampleRate: 0.2, // 20% dos fetch viram trace e levam traceparent
propagateTraceTo: ['api.suaempresa.com.br'], // sem isto, só a mesma origem recebe o header
});
// Erro causado por uma resposta: entra no trace do fetch que o causou.
const response = await fetch('https://api.suaempresa.com.br/pedidos');
if (!response.ok) tracker.captureException(new Error('pedido falhou'), {}, { cause: response });- Só fetches amostrados levam
traceparent. SempropagateTraceTo, só a mesma origem do site recebe o header. - Se a API fica em outro domínio, o CORS da sua API precisa aceitar o header
traceparent(emAccess-Control-Allow-Headers); sem isso o navegador bloqueia a chamada. - A API com o SDK Node continua o trace: no waterfall aparecem o span do navegador, o fetch e os spans do servidor.
- Um erro causado por um fetch amostrado entra no trace dele, junto da API que o atendeu: o erro que o próprio fetch lançou, um erro cuja
causeaponta para ele ou para aResponse, oucaptureException(err, attrs, { cause: response }). Erro sem vínculo causal continua num trace próprio. Exige a versão 0.4.0 ou mais nova.
Source maps
Para o stack de erros minificados apontar para o código-fonte, envie os .map no CI com a mesma release passada ao init, e remova-os do que vai para o ar:
# No CI, depois do build do front (chave de servidor; nunca no bundle)
FG_TRACKER_KEY=$FG_TRACKER_KEY FG_TRACKER_URL=https://tracker-api.fortground.com.br \
npx -p fg-tracker-sdk fg-tracker-sourcemaps --dir dist --release "checkout-web@$GITHUB_SHA" --url-prefix "~/assets"
find dist -name '*.map' -deleteO upload usa a chave de servidor (no modo restrito, a pública recebe 403). O CLI vem no pacote fg-tracker-sdk.
Pageviews e consentimento
analytics: trueliga visitantes anônimos (cookies first-partyfgt_videfgt_sid) e pageviews, inclusive em navegação de SPA.consent: 'pending'guarda os pageviews em memória, sem cookies, atétracker.setConsent('granted');'denied'descarta. O consentimento vale só para pageviews: erros continuam sendo enviados, com a URL completa e o usuário desetUser.navigator.doNotTrackdesliga os pageviews. O pageview guarda só o caminho e os parâmetrosutm_*.
Envio e limites
- Lote a cada 1,5 s. Ao fechar a página, o restante sai por
sendBeacon(com a chave em?key=), erros primeiro. - O navegador limita a cerca de 64 KiB o que pode ficar em voo ao fechar a página: eventos acima de 48 KiB são cortados e marcados com
fg.truncated. - Rede, 408,
429e 5xx: reenvio com backoff ouRetry-After.413divide o lote; outro 4xx descarta. sampleRate(padrão 1) controla a fração de erros enviados;beforeSendfiltra ou altera cada evento.