Unique Pageviews in Google Analytics 4 (GA4)

How to track unique pageviews in GA4

Unique pageviews disappeared as a metric when Google Analytics 4 replaced Universal Analytics, but the number it measured is still fully recoverable in GA4 today.

This post originally documented a custom-event workaround from the early GA4 migration days. GA4 has matured since then, so this update covers the modern answers first: the built-in metric that matches unique pageviews almost exactly, the Explorations recipe, and the BigQuery SQL for when you need the number to be precise. The original do-it-yourself method remains at the end for setups that still use it.

What Unique Pageviews Measured

In Universal Analytics, Pageviews counted every view including refreshes and back-button returns, while Unique Pageviews counted a page at most once per session. Unique pageviews answered the question “how many sessions included this page,” which made it the honest number for comparing content popularity.

GA4’s event model dropped the metric, and its two obvious replacements answer different questions: Views counts every page_view event like UA’s Pageviews did, and Total Users counts people across their whole history rather than per session.

The Modern Equivalent: Sessions per Page

Here’s what the migration-era articles, including the original version of this one, could not say yet: GA4’s Sessions metric, scoped to a page dimension, is unique pageviews. A session is counted against a page at most once no matter how many times the page was viewed within it, which is the same definition UA used.

To see it in the standard interface:

  1. Go to Reports → Engagement → Pages and screens
  2. The default table shows Views and Users; click the pencil (Customize report) or simply add the Sessions metric to the report
  3. Sessions per page path is your unique pageviews column, sitting next to Views for the duplicate-inflated comparison

GA4 also ships Views per session as a standard metric now, which the early GA4 releases lacked, so the ratio the two UA metrics implied is available directly.

The Explorations Recipe

For a reusable report rather than a customized standard one:

  1. Open Explore and create a blank Free form exploration
  2. Dimension: Page path and screen class
  3. Metrics: Sessions and Views
  4. Sort by Sessions descending

The Sessions column reads as unique pageviews per page; the gap between Views and Sessions on any row shows how much refresh and revisit behavior that page gets, which is itself useful for spotting reference content people keep returning to within a visit.

The Precise Number: BigQuery

GA4’s free BigQuery export makes the exact UA definition a short query, counting each page once per distinct session:

SELECT
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page,
  COUNT(DISTINCT CONCAT(
    user_pseudo_id,
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id')
  )) AS unique_pageviews,
  COUNT(*) AS views
FROM `your-project.analytics_XXXXXX.events_*`
WHERE event_name = 'page_view'
  AND _TABLE_SUFFIX BETWEEN '20260901' AND '20260930'
GROUP BY page
ORDER BY unique_pageviews DESC;

This is unsampled, joins cleanly against anything else in your warehouse, and sidesteps GA4’s interface thresholds entirely. If you’re heading down this road, my GA4 BigQuery SQL recipes post covers this pattern alongside the other UA metrics people miss.

The Original DIY Method: A Custom Event

Before Sessions-by-page and Views per session existed in GA4’s reports, the workaround was tracking uniqueness yourself with a first-party cookie and a custom event. The approach still works and remains useful when you want unique-view logic with rules GA4 doesn’t offer, like a custom session window.

The snippet tracks viewed paths in a 30-minute cookie using the js-cookie library, and fires a unique_pageview event only on the first view of each path per session:

const cookie = Cookies.withAttributes({ path: '/', domain: location.hostname, secure: true, expires: 30 / 1440 });

(function uniquePageview() {
  let seen = [];
  try {
    seen = JSON.parse(cookie.get('unique-pageviews') || '[]');
  } catch (e) {}

  const path = location.pathname;
  if (seen.includes(path)) {
    return;
  }

  seen.push(path);
  cookie.set('unique-pageviews', JSON.stringify(seen));

  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'unique_pageview',
    page_path: path,
  });
})();

In Google Tag Manager, a Custom Event trigger on unique_pageview feeding a GA4 event tag completes the setup, and the event count per page path becomes your metric. Mark it as a key event if you want it available in standard reports.

Which One to Use

Use Sessions in Pages and screens for day-to-day content comparison, the Explorations version when you want it saved and shareable, and BigQuery when the number feeds decisions or dashboards and has to be exact. The custom event is the fallback for session logic GA4 doesn’t support natively. All four give you back the honest per-session page count that unique pageviews always was.