Implementasi Analytics Claude Code: GA4, GSC, Cloudflare, PV, Revenue
Implementasi analytics Claude Code dengan GA4, GSC, Cloudflare, PV, CTA, revenue events, dan tes.
Analytics bukan sekadar memasang tag
Implementasi analytics berarti mengubah PV, klik, artikel selesai dibaca, inquiry, klik produk, dan purchase path menjadi data untuk keputusan. PV adalah page view. Event adalah catatan aksi pengguna. Conversion atau GA4 key event adalah aksi yang dianggap hasil bisnis. UTM adalah label campaign di URL. Consent adalah aturan apakah browser boleh mengirim data analytics.
Claude Code berguna karena bisa mengubah measurement plan menjadi kode, tes, dan dokumentasi. Kesalahan Masa di situs ini adalah melihat PV naik tanpa memisahkan klik produk, form inquiry selesai, dan signup resource gratis. Traffic terlihat sehat, tetapi jalur revenue tidak terlihat.
Stack praktis di artikel ini: GA4 untuk campaign dan key event, Search Console untuk query dan halaman, Cloudflare untuk sinyal edge, Plausible untuk goal ringan, PostHog untuk funnel. Baca juga SEO optimization, A/B testing, performance, dan content funnel audit.
Measurement plan dulu
Minta Claude Code membuat tabel dari keputusan, bukan dari daftar tools.
Buat analytics implementation plan untuk content site ini.
Tujuannya bukan hanya PV growth, tetapi article completion, CTA click, inquiry, product click, dan purchase path.
Gunakan business_question, event_name, trigger, required_params, provider, decision.
Gunakan GA4 recommended events jika cocok. Custom events memakai snake_case.
| business_question | event_name | trigger | required_params | provider | decision |
|---|---|---|---|---|---|
| Artikel dibaca sampai akhir? | article_read_complete | Footer 70% terlihat | slug, category, reading_time_sec | GA4/PostHog | Perbaiki intro, heading, internal link |
| CTA diklik? | cta_click | CTA produk, training, atau PDF | slug, cta_id, cta_type, target_url | GA4/Plausible/PostHog | Ubah posisi dan copy |
| Inquiry selesai? | generate_lead | Form berhasil dikirim | form_id, lead_source, value, currency | GA4/PostHog | Perbaiki form dan offer |
| Produk membuat niat beli? | purchase_link_click | Klik produk atau Gumroad | product_id, price, currency, slug | GA4/PostHog | Cocokkan artikel dan produk |
| Query mana bernilai? | gsc_query_page | Search Console API mengembalikan page/query | page, query, clicks, impressions, ctr, position | GSC | Prioritaskan title dan update |
| Tag browser kehilangan traffic? | edge_page_view | Cloudflare Worker menerima request | path, country, status, duration_ms | Cloudflare | Temukan blocker dan isu speed |
Periksa event GA4 di recommended events. Gunakan generate_lead saat cocok; gunakan custom event untuk aksi artikel.
flowchart LR
Reader["Pembaca"]
Consent["Consent"]
Browser["browser analytics.js"]
Server["GA4 Measurement Protocol"]
GSC["Search Console API"]
Edge["Cloudflare Worker"]
Dashboard["Konten, revenue, kualitas"]
Reader --> Consent --> Browser
Browser --> Server
GSC --> Dashboard
Edge --> Dashboard
Browser --> Dashboard
Server --> Dashboard
Event contract dalam JS
Contract menjaga nama event dan parameter tetap konsisten.
// 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/" }));
}
Pisahkan products dan training. Klik produk berarti minat pada template atau guide; klik training berarti minat adopsi tim atau konsultasi.
Browser layer
Layer ini menangani consent, UTM, pembersihan parameter, dan pengiriman ke GA4/Plausible/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);
}
Kirim generate_lead setelah form sukses, bukan saat tombol submit diklik. Article completion cukup dikirim sekali saat bagian akhir artikel terlihat.
GA4, GSC, Cloudflare
Event yang dipastikan server memakai GA4 Measurement Protocol dan diuji dengan 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");
}
Data Search Console diambil lewat 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));
}
Untuk edge, lihat Workers Analytics Engine dan contoh 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 });
},
};
Jangan simpan email, nama, teks bebas, atau IP mentah di Cloudflare.
Use case dan pitfall
Use case 1: SEO. GSC impressions tinggi dan CTR rendah berarti title/description perlu diperbaiki. PV tinggi tetapi completion rendah berarti intro, struktur, atau contoh kode tidak sesuai intent. Use case 2: produk. purchase_link_click dengan product_id, price, currency, slug menunjukkan artikel yang mendorong revenue. Use case 3: konsultasi. cta_click adalah minat; generate_lead adalah form sukses. Use case 4: campaign. UTM harus disimpan sejak landing pertama.
Pitfall: nama event berubah-ubah, mengirim sebelum consent, konversi ganda client/server, menganggap GSC sebagai log lengkap, dan terlalu banyak script yang merusak Core Web Vitals. Pisahkan dashboard menjadi content growth, revenue funnel, dan technical quality. Dalam 24 jam, cek GA4 DebugView, Realtime, Plausible Goals, PostHog Events, dan agregat Cloudflare.
Untuk merapikan setup yang ada, gunakan products untuk template atau training untuk review measurement plan, implementasi, dan dashboard bersama tim.
PDF gratis: cheatsheet Claude Code
Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.
Kami menjaga datamu dan tidak mengirim spam.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.