Single-page apps

How client-side navigations are counted, and what hash routing needs.

Single-page apps change the URL without loading a new document, so a naive tag counts one pageview per session. Ours does not: it wraps the History API and counts the navigations your framework performs.

This is on by default. React Router, Next.js, Vue Router, SvelteKit and anything else built on pushState work with no configuration at all.

Hash routing

Apps that route on the fragment (#/dashboard) never touch the History API, so add data-hash="true". The fragment then becomes part of the tracked URL.

<script defer data-domain="example.com" data-hash="true"
        src="https://causalit.fr/js/s.js"></script>

Duplicate pageviews

Consecutive navigations to the same URL are collapsed into one. Frameworks that call replaceState on every render would otherwise inflate your numbers — an inflated number is worse than no number.

Turning it off

Set data-spa="off" if you would rather emit pageviews yourself, then call the tag manually at the moments that count as a page in your product.

Start free

Single-page apps — causalIT