Single-page application (SPA) analytics
Single-page applications (SPAs) update the view via JavaScript without a full page reload, so the default pageview that fires on load only happens once. To measure SPA navigation, analytics must fire 'virtual pageviews' on route changes. Getting this right — and consistent — is the main data-quality challenge when measuring SPAs.
What this means
In a classic multi-page site, each navigation reloads the page and fires a pageview. In an SPA, the framework swaps content client-side using the History API, so no reload occurs and the default pageview fires only on the first load.
To measure subsequent navigations, the app must explicitly send a 'virtual pageview' when the route changes.
How to handle it
Hook into the router or History API events and fire a pageview on each route change, passing the new path. Be careful to fire once per navigation — duplicate listeners or double renders can inflate counts — and to use the canonical path so reports group correctly.
- Default pageview fires only on first load in an SPA
- Fire virtual pageviews on route change
- Avoid duplicate fires that inflate counts
Why counts diverge
Different tools and configurations handle virtual pageviews differently, so SPA pageview counts can vary between tools even on the same site. When comparing, confirm both are counting route changes the same way before treating a difference as a bug.
How it appears in analytics and logs
If an SPA shows far fewer pageviews than expected, virtual pageviews on route change are likely missing; inflated counts can mean they fire too often.
Diagnostic use case
Use this when instrumenting an SPA so route changes are measured correctly and pageview counts are not silently under- or over-reported.
What WebmasterID can help detect
WebmasterID records page_view events first-party, including for client-rendered navigations when instrumented; this page explains the SPA measurement challenge.
Common mistakes
- Forgetting to fire virtual pageviews on route change.
- Firing duplicate pageviews from double-registered listeners.
- Comparing SPA pageviews across tools with different rules.
Privacy and accuracy notes
Virtual pageview tracking counts render events, not identity, and needs no personal data by itself; consent rules still depend on what else you collect. This is educational, not legal advice.
Related pages
- Pageviews: what the metric counts
A pageview is recorded when a page is loaded (or a virtual page is rendered in a single-page app). It is the oldest web-analytics metric and the easiest to misread: pageviews count loads, not people, and modern apps and prefetching can inflate or hide them. This page defines the metric and its caveats.
- The page_view event: the base of web analytics
page_view is the event fired when a page loads. It is the base of almost every web-analytics model: sessions, pageviews, and most reports build on it. In classic sites the tracker fires it automatically on load; in single-page apps you fire it on each route change. Its properties (path, title, referrer) drive most downstream reports.
- Server-side vs client-side analytics collection
Analytics can be collected client-side (a browser script fires events) or server-side (the server or a server endpoint records them). The two see different things: client-side captures rich browser context but misses no-JavaScript clients and is affected by blockers, while server-side sees every request but lacks some browser-only signals. Many setups combine them.
- Events docs
Instrument page_view and custom events.
Sources and verification notes
Last reviewed 2026-06-24. Facts are checked against primary/official sources where available; uncertain specifics are marked “Data not yet verified” rather than guessed.