On this page
  1. Most frameworks need nothing
  2. The same address never counts twice
  3. Hash routing needs one attribute
  4. Page titles that don't match
  5. Full manual control
  6. How time on page works

Most frameworks need nothing

The script wraps the browser's history.pushState and history.replaceState and listens for back and forward navigation (popstate). Mainstream routers in history mode change pages through exactly those methods, so once the script is installed every route change records a pageview:

  • Vue Router (createWebHistory)
  • React Router (BrowserRouter)
  • Next.js (App Router and Pages Router)
  • Nuxt

Put the tag in the <head> of your root layout. With next/script in Next.js, use strategy="afterInteractive" and place it in the root layout only, not in each page component.

The same address never counts twice

If the new address equals the last recorded one, the change is ignored. A replaceState that only touches router state, not the URL, doesn't add a pageview.

The part after # is dropped by default as well: /docs#intro and /docs#faq are the same page, so in-page anchor jumps don't create new pageviews.

Hash routing needs one attribute

If your addresses look like https://example.com/#/pricing, the app uses hash routing (Vue Router's createWebHashHistory, older Angular setups and so on). Add data-hash="true" to the script:

<script defer src="https://static.pathclue.com/client.js" data-site="YOUR_SITE_KEY" data-hash="true"></script>

The script then keeps the hash and records a pageview on every hashchange. Without it, the whole app shows up in reports as a single page.

Page titles that don't match

After a route change, the script reads document.title on the next tick. Some frameworks and SEO plugins update the title later than that, so a page may be reported with the previous page's title. The address is always right. If titles matter to you, either have the router set the title synchronously, or read reports by path rather than title.

Full manual control

Occasionally you'll want to record the pageview only after data has loaded, or your router doesn't use the History API. You can switch off automatic collection and call the pageview method from your route callback. The exact snippet, with your site key filled in, is on Website analytics › Configuration › SDK code in the console.

Note that data-auto-track="false" also switches off time on page, outbound clicks and performance collection. If you only want to skip some pages, data-exclude is the better tool — see Script attributes reference.

How time on page works

When the route changes, the tab is hidden or the page closes, the script sends the time spent if the visitor stayed longer than one second. Each route in a single-page app gets its own time on page, the same way pages on a multi-page site do.

Next in this topicCustom events: names, properties and three ways to send them