Tips & Tricks (Atualizado: 03/06/2026)

Implementar Analytics com Claude Code: GA4, GSC, Cloudflare e Receita

Implemente analytics com Claude Code: GA4, GSC, Cloudflare, PV, CTA, receita e testes.

Implementar Analytics com Claude Code: GA4, GSC, Cloudflare e Receita

Analytics não é só instalar tag

Implementar analytics é transformar PV, cliques, leitura completa, contatos, cliques em produto e compras em dados que mudam decisões. PV significa page view, a visualização de uma página. Evento é uma ação registrada. Conversão ou key event no GA4 é um resultado de negócio. UTM é a marca de campanha na URL. Consentimento define se o navegador pode enviar dados.

Claude Code ajuda porque transforma plano de medição em código, testes e documentação. O erro que Masa encontrou no site foi acompanhar PV crescendo sem separar clique em produto, formulário concluído e cadastro em recurso gratuito. O tráfego parecia bom, mas a rota de receita não aparecia.

A pilha prática aqui é GA4 para campanhas e eventos-chave, Search Console para query e página, Cloudflare para sinais de borda, Plausible para metas leves e PostHog para funis. Leia também SEO optimization, A/B testing, performance e content funnel audit.

Plano de medição

Peça ao Claude Code uma tabela baseada em decisões.

Crie um plano de analytics para este site de conteúdo.
O objetivo não é só crescer PV, mas melhorar leitura completa, CTA, consultas, cliques em produto e compras.
Use business_question, event_name, trigger, required_params, provider, decision.
Use eventos recomendados de GA4 quando fizer sentido. Eventos próprios em snake_case.
business_questionevent_nametriggerrequired_paramsproviderdecision
O artigo é lido até o fim?article_read_completeRodapé 70% visívelslug, category, reading_time_secGA4/PostHogAjustar introdução, títulos e links
CTAs recebem clique?cta_clickCTA de produto, treinamento ou PDFslug, cta_id, cta_type, target_urlGA4/Plausible/PostHogMudar posição e texto
O contato foi concluído?generate_leadFormulário enviado com sucessoform_id, lead_source, value, currencyGA4/PostHogMelhorar formulário e oferta
Produto cria intenção?purchase_link_clickClique em produto ou Gumroadproduct_id, price, currency, slugGA4/PostHogCombinar artigo e produto
Quais queries valem esforço?gsc_query_pageSearch Console API retorna page/querypage, query, clicks, impressions, ctr, positionGSCPriorizar título e atualização
Tags de navegador perdem tráfego?edge_page_viewCloudflare Worker recebe requestpath, country, status, duration_msCloudflareVer bloqueios e velocidade

Confira eventos do GA4 em recommended events. Use generate_lead quando encaixar e deixe eventos próprios para ações do artigo.

flowchart LR
  Reader["Leitor"]
  Consent["Consentimento"]
  Browser["browser analytics.js"]
  Server["GA4 Measurement Protocol"]
  GSC["Search Console API"]
  Edge["Cloudflare Worker"]
  Dashboard["Conteúdo, receita, qualidade"]

  Reader --> Consent --> Browser
  Browser --> Server
  GSC --> Dashboard
  Edge --> Dashboard
  Browser --> Dashboard
  Server --> Dashboard

Contrato de eventos em JS

O contrato mantém nomes e parâmetros estáveis.

// event-plan.mjs
import { pathToFileURL } from "node:url";

export const eventPlan = {
  article_read_complete: { required: ["slug", "category", "reading_time_sec"], providers: ["GA4", "PostHog"] },
  cta_click: { required: ["slug", "cta_id", "cta_type", "target_url"], providers: ["GA4", "Plausible", "PostHog"] },
  generate_lead: { required: ["form_id", "lead_source", "value", "currency"], providers: ["GA4", "PostHog"] },
  purchase_link_click: { required: ["product_id", "price", "currency", "slug"], providers: ["GA4", "PostHog"] },
  campaign_landing: { required: ["utm_source", "utm_medium", "utm_campaign"], providers: ["GA4"] },
};

export function validateEvent(name, params = {}) {
  const contract = eventPlan[name];
  if (!contract) return { ok: false, missing: ["known_event_name"] };
  const missing = contract.required.filter((key) => params[key] === undefined || params[key] === "");
  return { ok: missing.length === 0, missing };
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  console.log(validateEvent("cta_click", { slug: "claude-code-analytics-implementation", cta_id: "products_footer", cta_type: "product", target_url: "/en/products/" }));
}

Separe products e training. Produto indica interesse em guia ou template; treinamento indica demanda de adoção em equipe.

Camada do navegador

Aqui ficam consentimento, UTM, limpeza de parâmetros e envio para GA4, Plausible e PostHog.

// browser-analytics.js
const CONSENT_KEY = "analytics_consent";
const UTM_KEYS = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];

function inBrowser() {
  return typeof window !== "undefined" && typeof localStorage !== "undefined";
}

function hasConsent() {
  return inBrowser() && localStorage.getItem(CONSENT_KEY) === "granted";
}

function cleanParams(params = {}) {
  return Object.fromEntries(Object.entries(params).filter(([, value]) => value !== undefined && value !== null && value !== "").map(([key, value]) => [key, typeof value === "boolean" ? Number(value) : value]));
}

export function setAnalyticsConsent(state) {
  if (!inBrowser()) return;
  localStorage.setItem(CONSENT_KEY, state);
  window.gtag?.("consent", "update", { analytics_storage: state, ad_storage: "denied" });
}

export function readUtmParams() {
  if (!inBrowser()) return {};
  const current = new URLSearchParams(window.location.search);
  const saved = JSON.parse(localStorage.getItem("landing_utm") || "{}");
  const next = { ...saved };
  for (const key of UTM_KEYS) {
    const value = current.get(key);
    if (value) next[key] = value;
  }
  localStorage.setItem("landing_utm", JSON.stringify(next));
  return next;
}

export function trackEvent(name, params = {}) {
  if (!hasConsent()) return;
  const payload = cleanParams({ ...readUtmParams(), ...params });
  window.gtag?.("event", name, payload);
  window.plausible?.(name, { props: payload });
  window.posthog?.capture(name, payload);
}

Envie generate_lead só depois do sucesso do formulário. Leitura completa deve disparar uma vez quando o final do artigo aparece.

GA4, GSC e Cloudflare

Eventos confirmados no servidor usam GA4 Measurement Protocol e validation server.

// ga4-server-event.mjs
import { pathToFileURL } from "node:url";

const { GA4_MEASUREMENT_ID, GA4_API_SECRET, GA4_DEBUG } = process.env;
if (!GA4_MEASUREMENT_ID || !GA4_API_SECRET) throw new Error("GA4_MEASUREMENT_ID and GA4_API_SECRET are required");

export async function sendGa4Event({ clientId, name, params = {} }) {
  const endpoint = new URL(GA4_DEBUG === "1" ? "https://www.google-analytics.com/debug/mp/collect" : "https://www.google-analytics.com/mp/collect");
  endpoint.searchParams.set("measurement_id", GA4_MEASUREMENT_ID);
  endpoint.searchParams.set("api_secret", GA4_API_SECRET);
  const response = await fetch(endpoint, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ client_id: clientId, events: [{ name, params }] }) });
  if (!response.ok) throw new Error("GA4 request failed with status " + response.status);
  if (GA4_DEBUG === "1") {
    const result = await response.json();
    if (result.validationMessages?.length) throw new Error(JSON.stringify(result.validationMessages, null, 2));
  }
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  await sendGa4Event({ clientId: "555.1234567890", name: "generate_lead", params: { form_id: "training", lead_source: "article_footer", value: 1, currency: "USD" } });
  console.log("sent");
}

Search Console vem pela Search Analytics API.

// gsc-query.mjs
import { pathToFileURL } from "node:url";

const { GSC_ACCESS_TOKEN, GSC_SITE_URL = "https://example.com/" } = process.env;
if (!GSC_ACCESS_TOKEN) throw new Error("GSC_ACCESS_TOKEN is required");

export async function querySearchConsole({ startDate, endDate, pageContains }) {
  const endpoint = "https://www.googleapis.com/webmasters/v3/sites/" + encodeURIComponent(GSC_SITE_URL) + "/searchAnalytics/query";
  const response = await fetch(endpoint, {
    method: "POST",
    headers: { authorization: "Bearer " + GSC_ACCESS_TOKEN, "content-type": "application/json" },
    body: JSON.stringify({ startDate, endDate, dimensions: ["page", "query"], dimensionFilterGroups: pageContains ? [{ filters: [{ dimension: "page", operator: "contains", expression: pageContains }] }] : [], rowLimit: 25 }),
  });
  if (!response.ok) throw new Error("Search Console request failed with status " + response.status);
  return response.json();
}

if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
  const data = await querySearchConsole({ startDate: "2026-05-01", endDate: "2026-05-31", pageContains: "/blog/claude-code-analytics-implementation" });
  console.log(JSON.stringify(data.rows ?? [], null, 2));
}

Para borda, use Workers Analytics Engine e o exemplo writeDataPoint.

// cloudflare-worker.js
function json(data, status = 200) {
  return new Response(JSON.stringify(data), { status, headers: { "content-type": "application/json" } });
}

export default {
  async fetch(request, env) {
    if (request.method !== "POST") return json({ ok: false, error: "method_not_allowed" }, 405);
    const event = await request.json().catch(() => null);
    if (!event?.event_name || !event?.slug) return json({ ok: false, error: "event_name_and_slug_required" }, 400);
    const country = request.cf?.country || request.headers.get("cf-ipcountry") || "XX";
    env.ANALYTICS?.writeDataPoint({ blobs: [event.event_name, event.slug, event.cta_id || "", country], doubles: [Number(event.value || 1)], indexes: [String(event.slug).slice(0, 96)] });
    return json({ ok: true });
  },
};

Não grave e-mail, nome, texto livre nem IP bruto no Cloudflare.

Casos de uso e armadilhas

Caso 1: SEO. Muitas impressões no GSC e CTR baixo pedem título e description melhores. PV alto e leitura baixa pedem intro e estrutura melhores. Caso 2: produtos. purchase_link_click com product_id, price, currency e slug mostra quais artigos levam a ofertas. Caso 3: consultoria. cta_click mede intenção; generate_lead mede formulário concluído. Caso 4: campanhas. UTM precisa sobreviver até o formulário.

Armadilhas: nomes inconsistentes, envio antes de consentimento, conversões duplicadas entre cliente e servidor, tratar GSC como log completo, excesso de scripts prejudicando Core Web Vitals. Divida dashboards em crescimento editorial, funil de receita e qualidade técnica. Verifique GA4 DebugView, Realtime, Plausible Goals, PostHog Events e Cloudflare em até 24 horas.

Para organizar uma instalação existente, products ajuda com templates e training ajuda a revisar plano, código e dashboards em equipe.

#Claude Code #analytics #tracking #React #TypeScript
Grátis

PDF grátis: cheatsheet do Claude Code

Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.

Cuidamos dos seus dados e não enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.