Route changes are tracked automatically. In most cases there is nothing to do.
What works out of the box
The script watches history.pushState, history.replaceState and popstate,
and records a page view whenever the path changes. That covers React Router,
Next.js, Vue Router, SvelteKit, Astro's view transitions, Remix, and anything
else that uses the History API — which is nearly everything.
You do not need to call window.truestat() on navigation, and you should not:
that would double-count.
Debouncing
Navigations are debounced at 100 ms.
Routers routinely call replaceState immediately after pushState — to
normalise a trailing slash, to write a scroll position, to add a query
parameter. Without the debounce, every single navigation would produce two page
views. If you have ever seen a page view count exactly double the truth in
another analytics tool, this is usually why.
The practical consequence: two genuine navigations less than 100 ms apart are recorded as one. That is a redirect, not a person reading two pages.
Hash routing
If your app routes on the fragment — /#/dashboard, /#/settings — the path
never changes, so nothing is recorded after the first load. Turn on hash
tracking:
<script
defer
data-website-id="ts_a1b2c3d4e5f6"
data-domain="example.com"
data-ts-track-hash="true"
src="https://truestat.io/js/t.js"
></script>The script then also listens for hashchange.
Only turn this on if you actually route on the hash. On a normal site the
fragment is an anchor link, and every jump to a #section heading would be
recorded as a page view.
What the path looks like
The recorded path is location.pathname — no origin, no query string, no
fragment (unless hash tracking is on, in which case the fragment is included).
It is truncated at 500 characters. Long faceted-search URLs and deep documentation trees can exceed that; the tail is dropped and the view is still recorded.
Framework-specific advice
Do not add the script from inside a component's effect hook. Two things go wrong. A cleanup function that removes the script tears the tracker down on navigation. And a component that remounts adds a second copy of the script, which double-counts every view from then on.
Put the tag in your root HTML document or root layout — the file that renders once for the whole app. Every install page in Installing TrueStat names that file for its platform.
Verifying it
The clearest check is a count, not a state:
Load your app.
Navigate to three different routes.
Open your dashboard and look at Top pages.
You should see four paths, once each. If you see each one twice, you have two tags on the page — see Duplicate events. If you only see the first, your tag is in a page component rather than the root layout.