GA4 setup, event taxonomy, custom dimensions, conversion tracking, audience segments, and reporting automation.
Before touching GA4, define what matters:
| Layer | Question | Example |
|---|---|---|
| Business objective | What's the goal? | Increase trial signups 20% |
| KPI | How do we measure? | Trial signup rate, activation rate |
| Events | What do we track? | sign_up, tutorial_complete, plan_selected |
| Dimensions | What context? | plan_type, referral_source, user_role |
Use a consistent naming convention. Never use spaces or capitals in event names.
Naming pattern: object_action (noun_verb)
# Core events (auto-collected — don't recreate)
page_view, session_start, first_visit, user_engagement
# Recommended events (use GA4 standard names)
sign_up, login, purchase, add_to_cart, begin_checkout
# Custom events (your business logic)
trial_started
feature_activated
plan_upgraded
invite_sent
onboarding_completed
support_ticket_opened
Implementation (gtag.js):
// Custom event with parameters
gtag('event', 'trial_started', {
plan_type: 'pro',
referral_source: 'pricing_page',
value: 49
});
// User property (set once per user)
gtag('set', 'user_properties', {
account_type: 'enterprise',
company_size: '50-200'
});
GTM dataLayer push:
dataLayer.push({
event: 'plan_upgraded',
plan_from: 'free',
plan_to: 'pro',
mrr_delta: 49
});
Register in GA4 Admin → Custom definitions before sending data.
| Scope | Dimension | Example values | Use |
|---|---|---|---|
| Event | plan_type | free, pro, enterprise | Segment by plan |
| Event | feature_name | dashboard, export, api | Feature adoption |
| User | account_type | individual, team, enterprise | User segmentation |
| User | signup_source | organic, paid, referral | Acquisition quality |
Mark key events as conversions in GA4 Admin → Events → toggle "Mark as conversion."
High-value conversions:
sign_up — new account createdpurchase — payment completedtrial_started — trial activatedplan_upgraded — expansion revenueMicro-conversions (track but don't optimize ads against):
onboarding_completedfeature_activatedinvite_sentBuild in GA4 → Audiences for remarketing and analysis:
| Audience | Condition | Use |
|---|---|---|
| Active trial users | trial_started in last 14 days AND session_count > 3 | Nurture campaigns |
| Power users | feature_activated count > 10 in 30 days | Upsell targeting |
| Churned users | last_active > 30 days AND account_type = paid | Win-back campaigns |
| High-intent visitors | Viewed pricing page 2+ times, no signup | Retargeting ads |
For multi-domain setups (app.example.com + www.example.com):
gtag('config', 'G-XXXXXXX', {
linker: {
domains: ['example.com', 'app.example.com', 'checkout.example.com']
}
});
Verify in GA4 DebugView — sessions should NOT restart across domains.
GA4 Admin → Attribution settings:
Connect GA4 as data source. Key dashboard pages:
Overview dashboard:
Acquisition dashboard:
Engagement dashboard:
GA4 DebugView: Enable with:
gtag('config', 'G-XXXXXXX', { debug_mode: true });
Or install GA Debugger Chrome extension.
Common issues:
Query data programmatically:
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import RunReportRequest, DateRange, Dimension, Metric
client = BetaAnalyticsDataClient()
request = RunReportRequest(
property=f"properties/{PROPERTY_ID}",
date_ranges=[DateRange(start_date="30daysAgo", end_date="today")],
dimensions=[Dimension(name="sessionSource"), Dimension(name="sessionMedium")],
metrics=[Metric(name="sessions"), Metric(name="conversions")],
)
response = client.run_report(request)
for row in response.rows:
print(row.dimension_values[0].value, row.metric_values[0].value)