> For the complete documentation index, see [llms.txt](https://docs.uxwizz.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.uxwizz.com/installation/adding-the-tracking-code/automatic-spa-pageview-tracking.md).

# Automatic SPA pageview tracking

A single-page application changes routes without loading a new HTML document. UXWizz records its initial page automatically; call `UST.trackNewPage()` after later navigation.

Prefer the [React Router](/installation/adding-the-tracking-code/add-tracker-to-react-router-app.md) or [Next.js](/installation/adding-the-tracking-code/add-tracker-to-next.js-app.md) integration when your application uses one of those routers. Use the generic listener below only when you cannot integrate with the router directly.

### Automatically track pageviews on a Single Page Application

Add this script once after the UXWizz initialization snippet. It observes History API and hash navigation and waits until the next animation frame before checking the URL.

```html
<script>
(() => {
    let lastTrackedUrl = window.location.href;

    const trackPageview = () => {
        const currentUrl = window.location.href;
        if (currentUrl === lastTrackedUrl) return;
        lastTrackedUrl = currentUrl;
        if (typeof window.UST?.trackNewPage === 'function') {
            window.UST.trackNewPage();
        }
    };

    const schedulePageview = () => requestAnimationFrame(trackPageview);
    for (const method of ['pushState', 'replaceState']) {
        const original = history[method];
        history[method] = function (...args) {
            const result = original.apply(this, args);
            schedulePageview();
            return result;
        };
    }
    window.addEventListener('popstate', schedulePageview);
    window.addEventListener('hashchange', schedulePageview);
})();
</script>
```

This treats any URL change, including query parameters and hashes, as a potential pageview. Adjust that rule if your app changes the URL for filters or other actions that should not count as a page.

Do not combine this listener with another call to `trackNewPage()` for the same navigation. A route change before the tracker loads cannot be recovered by this script. If content loads later than the next frame, use the application's content-ready event instead.

Test navigation, Back, and Forward in a fresh session. Check **Visitors** for one pageview per intended navigation and replay a full recording to confirm the new content appears.
