GA4 doesn't calculate conversion rate for you like Universal Analytics did. You need to send custom events to track what counts as a conversion, then calculate the rate yourself. We'll walk through the entire setup.
Send Conversion Events with gtag.js
GA4 requires custom events for conversions. Start by instrumenting your site to send events like 'purchase', 'sign_up', or 'upgrade'.
Install gtag.js and Send Conversion Events
Add the Google Analytics tag to your site (Google provides it in Admin > Data Collection > Web > Installation Instructions). Then use gtag('event', ...) to send custom events whenever a conversion happens.
// Send a purchase event (e-commerce conversion)
gtag('event', 'purchase', {
currency: 'USD',
value: 99.99,
items: [
{
item_id: 'SKU_123',
item_name: 'Premium Plan',
price: 99.99,
quantity: 1
}
]
});
// Send a custom conversion event
gtag('event', 'sign_up', {
method: 'email',
user_id: 'user_12345'
});Or Use Firebase SDK for Web Apps
If you're using Firebase in your app, use logEvent() instead. It's the same data flowing into GA4, just a different interface.
import { getAnalytics, logEvent } from 'firebase/analytics';
const analytics = getAnalytics();
logEvent(analytics, 'purchase', {
currency: 'USD',
value: 49.99,
transaction_id: 'tx_abc123',
items: [{ item_id: 'product_1', quantity: 1 }]
});Add Parameters for Segmentation
Include custom parameters in your events so you can slice conversion rate by traffic source, user segment, or campaign later. Parameters like user_segment, campaign_id, or device_type make reports more useful.
gtag('event', 'lead_generated', {
value: 0,
currency: 'USD',
user_segment: 'enterprise',
source_campaign: 'q1_2024_promo',
traffic_source: 'organic_search',
industry: 'saas'
});Mark Events as Conversions in GA4
Once events are sending, configure GA4 to recognize them as conversions. This enables conversion metrics in your reports.
Create a Conversion Event in Admin
Go to Admin (gear icon) > Events > Create Event. Select the event name from your data (e.g., 'purchase', 'sign_up') and save. GA4 will now track this event as a conversion.
// No code needed for this step—it's all in the GA4 UI.
// But you can verify which events are marked as conversions
// using the Admin API:
const adminApiCall = async (accessToken, propertyId) => {
const response = await fetch(
`https://analyticsadmin.googleapis.com/v1alpha/properties/${propertyId}/conversionEvents`,
{
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
}
}
);
const data = await response.json();
console.log('Configured conversions:', data.conversionEvents);
};Check the Conversions Report
Navigate to Reports > Monetization > Conversions (or Engagement > Conversions for non-e-commerce). You should see your events listed with conversion counts.
// Query conversion counts using the Data API
const queryConversions = async (accessToken, propertyId) => {
const body = {
dateRanges: [{ startDate: '2024-03-01', endDate: '2024-03-26' }],
dimensions: [{ name: 'eventName' }],
metrics: [
{ name: 'eventCount' } // Number of conversion events
],
dimensionFilter: {
filter: {
fieldName: 'eventName',
value: 'purchase' // Replace with your conversion event
}
}
};
const response = await fetch(
`https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
const data = await response.json();
const conversionCount = data.rows[0].metricValues[0].value;
console.log(`Total conversions: ${conversionCount}`);
};Calculate Conversion Rate
GA4 doesn't show conversion rate as a single metric. You calculate it: (conversions ÷ sessions) × 100.
Query Conversions and Sessions, Then Calculate
Use the Data API to fetch both conversions (event count) and total sessions, then divide. This works for any date range or segment.
const calculateConversionRate = async (accessToken, propertyId) => {
const body = {
dateRanges: [{ startDate: '2024-03-01', endDate: '2024-03-26' }],
metrics: [
{ name: 'eventCount' },
{ name: 'sessions' }
],
dimensionFilter: {
filter: {
fieldName: 'eventName',
value: 'purchase'
}
}
};
const response = await fetch(
`https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
const data = await response.json();
const conversions = parseInt(data.rows[0].metricValues[0].value);
const sessions = parseInt(data.rows[0].metricValues[1].value);
const conversionRate = (conversions / sessions) * 100;
console.log(`Conversions: ${conversions}`);
console.log(`Sessions: ${sessions}`);
console.log(`Conversion Rate: ${conversionRate.toFixed(2)}%`);
};Create a Custom Metric in GA4 Reports
Go to Reports > any report > Comparisons > Create metric > enter the formula eventCount / sessions * 100. Name it 'Conversion Rate' and save. Now it appears in your report.
// Create a custom metric via Admin API
const createCustomMetric = async (accessToken, propertyId) => {
const body = {
displayName: 'Conversion Rate (%)',
parameterName: 'conversion_rate_pct',
description: 'Purchases divided by sessions, multiplied by 100',
measurementUnit: 'PERCENT',
scope: 'EVENT',
expression: 'eventCount / sessions * 100' // GA4 formula syntax
};
const response = await fetch(
`https://analyticsadmin.googleapis.com/v1alpha/properties/${propertyId}/customMetrics`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
const data = await response.json();
console.log('Custom metric created:', data.name);
};Segment by Traffic Source or Device
In Reports, add dimensions like sessionDefaultChannelGroup, deviceCategory, or country to see how conversion rate varies. This tells you which channels convert best.
// Query conversion rate by traffic source
const queryConversionRateByChannel = async (accessToken, propertyId) => {
const body = {
dateRanges: [{ startDate: '2024-03-01', endDate: '2024-03-26' }],
dimensions: [
{ name: 'sessionDefaultChannelGroup' } // Organic, Paid, Direct, etc.
],
metrics: [
{ name: 'eventCount' },
{ name: 'sessions' }
],
dimensionFilter: {
filter: {
fieldName: 'eventName',
value: 'purchase'
}
}
};
const response = await fetch(
`https://analyticsdata.googleapis.com/v1beta/properties/${propertyId}:runReport`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
const data = await response.json();
data.rows.forEach(row => {
const channel = row.dimensionValues[0].value;
const conversions = parseInt(row.metricValues[0].value);
const sessions = parseInt(row.metricValues[1].value);
const rate = (conversions / sessions) * 100;
console.log(`${channel}: ${rate.toFixed(2)}%`);
});
};Common Pitfalls
- Forgetting that GA4 auto-collects events like
page_viewandclick, but not your business conversions. You must send custom events for 'purchase', 'sign_up', or 'lead'. Auto-collected events alone won't track conversions. - Confusing 'eventCount' with unique conversions. If one user completes two purchases in a session, that's 2 conversion events, not 1 unique conversion. Know the difference for accurate rate calculation.
- Marking too many events as conversions in GA4 Admin. Use conversions only for actions that represent real business value (revenue, signups, demo requests). Marking every event dilutes your conversion metrics.
- Assuming GA4 calculates conversion rate automatically. Unlike Universal Analytics, GA4 shows event counts only. You must divide by sessions yourself or create a custom metric formula.
Wrapping Up
You now have conversion rate tracking in GA4. Send custom conversion events with gtag.js or Firebase SDK, mark them as conversions in Admin, then calculate rate using the Data API or a custom metric. If you want to track this automatically across tools, Product Analyst can help.