SPA Support

Klar automatically tracks client-side navigation in single-page applications.

How It Works

Klar automatically intercepts the History API to detect page navigation:

  • Wraps history.pushState (a router moving to a new page)
  • Listens for popstate events (back/forward navigation)
  • Records exactly one page view each time either one changes the pathname

No configuration needed for most frameworks!

What Counts as a Navigation

  • Counted: pushState or back/forward to a different pathname records one page view for the new path.
  • Not counted: replaceState. Frameworks call it for scroll restoration, shallow routing and state sync, not for navigation, so Klar does not wrap it.
  • Not counted: a change to the query string or the #hash only. Klar keys pages on the pathname, so /pricing?plan=pro and /pricing#faq are the same page as /pricing.
  • Collapsed: the same path reported twice within 1.5 seconds (hydration or double initialisation) counts once.

Hash-Based Routers

Klar does not auto-track hash routes (#/settings, Vue Router createWebHashHistory(), Angular withHashLocation(), React Router HashRouter): the pathname never changes, so to Klar the whole app is one page. Report each route yourself with klar.page(path):

window.addEventListener('hashchange', () => {
  klar.page(location.hash.slice(1) || '/');
});

#/settings is then recorded as /settings. Prefer your router's own after-navigation hook when it has one (see the Vue example below).

Supported Frameworks

Klar works out of the box with:

  • React Router
  • Vue Router
  • SvelteKit
  • Next.js (client-side navigation)
  • Nuxt
  • Ember
  • Backbone.js
  • Any framework using the History API

Manual Tracking

If automatic tracking doesn't work for your setup, you can manually track page views:

// After navigation completes
klar.trackPageview();

React Example

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function Analytics() {
  const location = useLocation();

  useEffect(() => {
    klar.trackPageview();
  }, [location.pathname]);

  return null;
}

Vue Example

import { onMounted } from 'vue';
import { useRouter } from 'vue-router';

router.afterEach((to) => {
  klar.trackPageview(to.fullPath);
});

Disabling Auto-Tracking

If you want to disable automatic SPA tracking:

<script 
  src="https://klar.alphabros.eu/klar.v2.js" 
  data-site-id="your-site-id"
  data-auto-track="false"
  defer
></script>