6 min read

How to Monitor Pages Per Session in Google Analytics 4

Your users aren't exploring your site as much as you thought. Pages per session tells you how many pages users view before leaving — and it's calculated differently in GA4 than it was in Universal Analytics. If this metric is dropping, it signals engagement problems. If it's rising, you've got a solid content strategy. Either way, you need to monitor it accurately.

Access Pages Per Session Data in GA4 Reports

GA4 doesn't use the old "Pages per Session" metric anymore. Instead, it uses engagement metrics like average engagement time and screen page views. Here's how to find the data you need.

Step 1: Navigate to the Engagement Report

Open GA4 and go to Reports > Engagement > Pages and screens. This shows individual pages ranked by user engagement, with data broken down by traffic source, device, and audience. You'll see screen page views and sessions here, which you can use to calculate pages per session manually.

Step 2: Create a Custom Report with Key Metrics

The default report doesn't show pages per session in one column. Click Customize this report in the top right. Add dimensions like Default Channel Grouping or Device Category, then add metrics Screenpage Views and Sessions. You can manually divide these columns to get pages per session by segment.

Step 3: Query Pages Per Session Programmatically with the Data API

For real-time dashboards or automated monitoring, use the Google Analytics Data API. This JavaScript example queries pages per session by device category over the last 30 days.

javascript
const {BetaAnalyticsDataClient} = require('@google-analytics/data');

const client = new BetaAnalyticsDataClient();

async function getPagesPerSession() {
  const request = {
    property: 'properties/YOUR_PROPERTY_ID',
    dateRanges: [{startDate: '30daysAgo', endDate: 'today'}],
    dimensions: [{name: 'deviceCategory'}],
    metrics: [{name: 'screenPageViews'}, {name: 'sessions'}],
  };
  
  const response = await client.runReport(request);
  
  response.rows.forEach(row => {
    const device = row.dimensions[0];
    const pageViews = parseInt(row.metricValues[0].value);
    const sessions = parseInt(row.metricValues[1].value);
    const pagesPerSession = (pageViews / sessions).toFixed(2);
    console.log(`${device}: ${pagesPerSession} pages/session`);
  });
}

getPagesPerSession();
Query the Data API to calculate pages per session by device
Watch out: GA4's screenPageViews metric counts each unique page in a session only once. If a user visits the same page twice, it still counts as one page view. Use pageviewCount in events if you need to count repeated pages.

Ensure Accurate Page Tracking with gtag.js

GA4 automatically tracks pageviews, but if your site is a single-page app (SPA), you need to manually fire page_view events. Otherwise, GA4 won't register navigation between sections and your pages per session will be artificially low.

Step 1: Verify GA4 Tracking Is Active

Check that your GA4 tracking code is installed in the head of your HTML or via Google Tag Manager. GA4 fires an automatic page_view event on initial page load. Open DevTools, go to the Network tab, and look for requests to google-analytics.com with your property ID (starting with G-).

javascript
<!-- GA4 tracking code -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>
Standard GA4 code snippet (replace G-XXXXXXXXXX with your property ID)

Step 2: Manually Fire Page View Events for SPAs

If you're using React, Vue, or Next.js, the page_view event doesn't fire on route changes. You need to manually trigger it when the user navigates. Use the gtag page_view event with the page_path parameter to track navigation.

javascript
// Track page views in a single-page app
function trackPageView(path) {
  gtag('event', 'page_view', {
    'page_path': path,
    'page_title': document.title,
    'page_location': window.location.href
  });
}

// Example: React Router
import {useEffect} from 'react';
import {useLocation} from 'react-router-dom';

export default function App() {
  const location = useLocation();
  
  useEffect(() => {
    trackPageView(location.pathname);
  }, [location.pathname]);
  
  return <div>Your app</div>;
}
Manually fire page_view events on route changes in React

Step 3: Verify Page View Events in Real Time

In GA4, go to Reports > Realtime and filter by the page_view event. Navigate your site and confirm that each page view appears in the real-time report. If pages per session is low but you're seeing navigation in realtime, check that your tracking code is actually firing.

javascript
// Add debug logging to confirm events are firing
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  'event': 'page_view',
  'page_path': window.location.pathname,
  'timestamp': new Date().toISOString(),
  'debug': true
});

console.log('Page view event pushed:', window.location.pathname);
Debug logging to verify page_view events are firing
Tip: If you're using Next.js or Remix, use a route-change handler in your layout component. GA4 won't auto-detect navigation in these frameworks without explicit tracking.

Monitor Pages Per Session with Alerts and Dashboards

Pages per session fluctuates with traffic quality and seasonality. Set up automated alerts so you catch drops before they impact your business.

Step 1: Create an Alert for Engagement Drops

Go to Admin > Alerts and click Create alert. Set the metric to Screenpage Views, define a threshold (e.g., alert if it drops 25% below the baseline), and choose who gets notified. GA4 sends alerts via email when the threshold is breached.

Step 2: Build a Trend Chart in Looker Studio

Connect GA4 to Looker Studio to track pages per session over time. Create a data source from GA4, then add a line chart with Date as the dimension and Screenpage Views and Sessions as metrics. Create a calculated field to divide pageviews by sessions for a continuous trend.

javascript
// Fetch 90-day trend data for export to Looker Studio
const request = {
  property: 'properties/YOUR_PROPERTY_ID',
  dateRanges: [{startDate: '90daysAgo', endDate: 'today'}],
  dimensions: [{name: 'date'}, {name: 'source'}],
  metrics: [{name: 'screenPageViews'}, {name: 'sessions'}],
  orderBys: [{dimension: {name: 'date'}}]
};

const response = await client.runReport(request);
const trends = response.rows.map(row => ({
  date: row.dimensions[0],
  source: row.dimensions[1],
  pagesPerSession: parseFloat(
    (parseInt(row.metricValues[0].value) / parseInt(row.metricValues[1].value)).toFixed(2)
  )
}));

console.table(trends);
Query 90-day trend data by traffic source for monitoring

Step 3: Segment by Traffic Source to Spot Problem Areas

Pages per session varies by traffic source. Organic search users often view more pages than paid ad clicks. In your custom report, add Default Channel Grouping as a dimension to see which channels have low engagement. If organic drops while paid stays flat, you have a content or SEO issue.

Watch out: Don't alert on raw pages per session changes without context. A spike in direct traffic or new device types can lower the average. Use percentage changes (25%+) and segment by source to avoid false alarms.

Common Pitfalls

  • Forgetting that GA4's screenPageViews metric counts unique pages in a session, not total clicks — repeat visits to the same page don't increase the count
  • Not manually tracking page_view events in single-page apps, resulting in missing navigation and severely undercounted pages per session
  • Confusing screenPageViews with events — screenPageViews is the metric for pages per session; eventCount includes all custom events and gives you inflated numbers
  • Setting up alerts on pages per session without segmenting by source or device, leading to noisy alerts that don't indicate real problems

Wrapping Up

Pages per session is a reliable signal of engagement depth. By querying GA4's Data API, ensuring SPAs track page views correctly, and monitoring trends with Looker Studio alerts, you'll catch engagement issues early and know exactly where users are dropping off. If you want to track this automatically across tools, Product Analyst can help.

Track these metrics automatically

Product Analyst connects to your stack and surfaces the insights that matter.

Try Product Analyst — Free