Skip to content
all posts
Guide 2 min read updated July 20, 2026

Getting analytics right in a single-page app

Why single-page apps break traditional pageview tracking, how to count route changes correctly, and how sonex handles SPA navigation automatically.

By Sourav · Building sonex
All posts

Single-page apps are fast because they never fully reload. That is also why they quietly break analytics. Traditional trackers count a pageview on page load, and a SPA only loads once, so every in-app navigation after that goes uncounted. Here is how to fix it, and why with sonex there is usually nothing to fix.

Why the pageview disappears

In a classic multi-page site, each link is a full navigation: the browser unloads, requests a new document, and the analytics script runs again, recording a pageview. A single-page app instead swaps content with JavaScript and updates the URL through client-side routing. No document loads, so a load-based tracker sees one pageview for an entire session.

The symptom is unmistakable: session counts look normal, but pages per visit is stuck near one and your interior routes barely register. The visits are real; the tracker just never heard about them.

The fix: listen to the History API

Client-side routers navigate by calling the browser’s History API, pushState and replaceState, and the browser fires popstate on back and forward. A SPA-aware tracker wraps those so each route change becomes a pageview.

pushState / replaceState  ->  count a pageview
popstate (back / forward) ->  count a pageview

That is the mechanism every correct SPA tracker uses under the hood.

How sonex handles it

sonex hooks the History API out of the box. Add the script once and client-side route changes are counted as pageviews automatically, with the navigation debounced so a single logical route change is not double counted.

<script defer
  src="https://api.trysonex.com/sonex.js"
  data-website-id="YOUR_WEBSITE_ID"></script>

For React Router, Vue Router, SvelteKit and the rest, which all navigate through the History API, that is the entire setup.

When you need manual control

A few routing patterns do not use the History API, or you may want a pageview only after data has loaded. For those, send one yourself by calling track with no arguments, which records a pageview for the current URL:

window.sonex.track();

Call it after your route resolves, and the interior view is counted exactly when you intend.

The result

With History-API tracking in place, a single-page app reports like a normal site: real pageviews per route, honest pages-per-visit, and funnels that follow people through your client-side flow, all without a cookie and without slowing the fast navigation that made you build a SPA in the first place.

Frequently asked questions

Why do single-page apps break analytics?
Traditional analytics counts a pageview on a full page load. A single-page app changes the URL and content with client-side routing and never reloads, so those in-app navigations go uncounted unless the tracker listens for route changes.
How does sonex track single-page app navigation?
sonex hooks the browser History API, pushState, replaceState and the popstate event, so client-side route changes are counted as pageviews automatically. For most SPAs you add the script once and nothing else.
Do I need to manually send pageviews in React or Vue?
Usually not. Because sonex listens to History API changes, framework routers that use it are tracked automatically. If you have an unusual routing setup, you can still send a pageview manually through the tracker API.

sonex is privacy-first web analytics. No cookies, no consent banner, no personal data. Drop one script and read realtime visitors, funnels and a world map in seconds.

Try sonex free
Questions

Frequently asked.

Cookies, install and pricing, answered. Still stuck? Ask us anything .

01 Can sonex show revenue next to my traffic?

Yes. Connect Stripe or Polar with a read-only key and sonex reads revenue straight from your payment provider, per website. Revenue then appears as a focusable series on the Overview chart and as its own report, beside the traffic that earned it. No tracked event is needed for it to work.

02 Does sonex use cookies?

No. sonex sets no cookies and needs no consent banner. It counts visits without cookies, fingerprinting, or any personal data, so it is GDPR, PECR and CCPA-ready by default.

03 How do I install sonex?

Add one script tag to your site's <head> with your website id. It is a single lightweight tracker — no build step and no SDK required.

04 Is sonex a Google Analytics alternative?

Yes. sonex gives you the reports that matter — visitors, pages, referrers, funnels, revenue and a world map — without surveilling your audience or drowning you in configuration.

05 How is sonex priced?

By monthly tracked events. Free covers 2k events, Pro is $20/mo for 200k events, and Business is $200/mo for 2M events with team seats.

See what your traffic actually earns.

Revenue beside the visitors that produced it. No cookies, no credit card, no consent banner.

Get started