You've got traffic, but you're losing users somewhere in your conversion journey. GA4's Funnel Exploration report shows exactly where drop-off happens—but only if you're sending the right events. We'll walk through building a funnel that actually tracks what matters in your product.
Set up events for each funnel step
A funnel is a sequence of events. You need to send those events to GA4 before you can analyze them.
Send a custom event for the first funnel step
Start with your signup flow. Fire an event when a user completes that step. Use gtag.js to send events from your app. Give each step a clear event name—something like signup_complete, not just click.
gtag('event', 'signup_complete', {
user_id: 'user_123',
method: 'email'
});Add events for each subsequent step
Add the same pattern for each step in your funnel. This could be email verification, profile setup, first action in the product, or checkout. Fire one event per completed step.
// Verification complete
gtag('event', 'email_verified', {
user_id: 'user_123'
});
// Profile setup done
gtag('event', 'profile_completed', {
user_id: 'user_123',
setup_time_seconds: 45
});
// First real action
gtag('event', 'create_report', {
user_id: 'user_123',
report_type: 'kpi_dashboard'
});Verify events in GA4 DebugView
Before building your funnel, confirm events are arriving. Open Admin > DebugView in GA4. Sign in with a test account and trigger your funnel steps. You should see each event fire in real-time.
// In development, enable debug mode to see events in DebugView
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true
});
// Send test event
gtag('event', 'test_event', {
'test_parameter': 'debug_value'
});purchase, not Purchase or make_purchase. Check your event naming convention and stick to it across all funnel steps.Build your funnel in GA4
Once events are flowing, create a Funnel Exploration report to visualize drop-off.
Open Funnel Exploration
Go to Explore > Funnel Analysis in your GA4 property. This opens a blank canvas for your funnel.
// Verify your GA4 property is set up correctly
// Use gtag to check that events are being sent to the right measurement ID
gtag('config', 'G-XXXXXXXXXX', {
'anonymize_ip': true,
'allow_google_signals': true
});Add steps to your funnel
Click Add step and select your first event (e.g., signup_complete). Then add the next step (email_verified), and keep going until you've defined your full conversion path. The order matters—GA4 calculates drop-off between consecutive steps.
// Funnel structure example:
// Step 1: signup_complete
// Step 2: email_verified
// Step 3: profile_completed
// Step 4: create_report
// GA4 calculates:
// - How many users reached step 1
// - Of those, how many reached step 2
// - Of those, how many reached step 3
// And so on...Segment and compare drop-off
Add segments to break down your funnel by user properties (e.g., traffic source, user type, device). Use Add comparison to see how drop-off changes across different cohorts. This reveals where specific user groups struggle.
Query funnel data with the Reporting API
For larger funnels or scheduled reporting, pull funnel data programmatically using the Google Analytics Data API.
Authenticate and create a Data API client
Install the Google Analytics Data library and authenticate with a service account. This gives you programmatic access to query your funnel data.
const {BetaAnalyticsDataClient} = require('@google-analytics/data');
const analyticsDataClient = new BetaAnalyticsDataClient({
projectId: 'YOUR_GCP_PROJECT_ID'
// Uses GOOGLE_APPLICATION_CREDENTIALS env var for credentials
});Call runFunnelReport to get funnel metrics
Use the runFunnelReport method to query your funnel. Specify each step by event name and get back the user counts at each stage. This lets you calculate drop-off rates programmatically.
const response = await analyticsDataClient.runFunnelReport({
property: 'properties/PROPERTY_ID',
dateRanges: [{
startDate: '2024-01-01',
endDate: '2024-03-26'
}],
funnels: [{
steps: [
{eventName: 'signup_complete'},
{eventName: 'email_verified'},
{eventName: 'profile_completed'},
{eventName: 'create_report'}
]
}],
metrics: [{name: 'activeUsers'}]
});Parse results to calculate drop-off
The API returns user counts at each step. Divide step 2 by step 1 to get your first-step completion rate, step 3 by step 2 for the next, and so on. This shows where your biggest leaks are.
const funnelData = response.funnelTable.rows;
// Each row represents one step
const step1Users = parseFloat(funnelData[0].metrics[0].value);
const step2Users = parseFloat(funnelData[1].metrics[0].value);
const step3Users = parseFloat(funnelData[2].metrics[0].value);
const step1To2Rate = (step2Users / step1Users) * 100;
const step2To3Rate = (step3Users / step2Users) * 100;
console.log(`Step 1 → 2: ${step1To2Rate.toFixed(2)}%`);
console.log(`Step 2 → 3: ${step2To3Rate.toFixed(2)}%`);Common Pitfalls
- Forgetting that GA4 requires events in order within a 24-hour window—old funnels with stale definitions won't capture users who complete steps days apart.
- Sending redundant or overlapping events. If you fire
add_to_cartevery time the user views the cart, you'll get inflated numbers. Send events only when the actual step completes. - Using default PageView events for your funnel. Custom events are cleaner and more reliable. Define them intentionally for each step.
- Not accounting for data processing delays. GA4 usually updates within a few hours, but real-time data can lag. Don't expect yesterday's funnel results until the next morning.
Wrapping Up
You now have events flowing, a funnel built in GA4, and a way to query that funnel programmatically. Watch for drop-off spikes and use segments to find which user groups struggle. If you want to track this automatically across tools, Product Analyst can help.