Single-page apps
Automatic tracking for React, Vue, Next.js, and other SPAs.
Automatic navigation tracking
The Glyphex tracking script automatically detects client-side navigation in single-page applications. No additional configuration needed.
It works by listening to the History API (pushState and popstate events), which all modern frameworks use for routing.
Just add the script once - it handles all navigation automatically.
Framework examples
Next.js (App Router)
// app/layout.tsx
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html>
<head>
<Script
defer
data-site-id="YOUR_SITE_ID"
src="https://glyphex.io/tracker.js"
strategy="afterInteractive"
/>
</head>
<body>{children}</body>
</html>
)
}Next.js (Pages Router)
// pages/_app.tsx
import Script from 'next/script'
export default function App({ Component, pageProps }) {
return (
<>
<Script
defer
data-site-id="YOUR_SITE_ID"
src="https://glyphex.io/tracker.js"
strategy="afterInteractive"
/>
<Component {...pageProps} />
</>
)
}React Router
// index.html - just add the script <script defer data-site-id="YOUR_SITE_ID" src="https://glyphex.io/tracker.js" ></script> // Navigation is tracked automatically!
Vue / Nuxt
<!-- nuxt.config.ts -->
export default defineNuxtConfig({
app: {
head: {
script: [
{
defer: true,
'data-site-id': 'YOUR_SITE_ID',
src: 'https://glyphex.io/tracker.js'
}
]
}
}
})SvelteKit
<!-- src/app.html -->
<!DOCTYPE html>
<html>
<head>
<script
defer
data-site-id="YOUR_SITE_ID"
src="https://glyphex.io/tracker.js"
></script>
</head>
<body>
%sveltekit.body%
</body>
</html>Astro
<!-- src/layouts/Layout.astro -->
<html>
<head>
<script
defer
data-site-id="YOUR_SITE_ID"
src="https://glyphex.io/tracker.js"
></script>
</head>
<body>
<slot />
</body>
</html>How it works
The tracking script:
- Tracks the initial page load
- Listens for
pushStatecalls (new navigation) - Listens for
popstateevents (back/forward navigation) - Sends a page view when the URL changes
Hash-based routing
If your app uses hash-based routing (e.g., example.com/#/page), those hash-only route changes are not tracked automatically. Use History API routing, or call window.analytics.track() yourself on each change.
Page titles
After a route change the pageview is sent 300 ms later, so document.title already holds the new page's title. Time on page for the page you left is sent immediately.
Troubleshooting
Page views not tracked on navigation?
Ensure the script is loaded before your first navigation occurs. Using defer or strategy="afterInteractive" is recommended.
Duplicate page views?
Make sure you haven't added the script multiple times (once is enough). Also check that you're not manually calling the tracker in addition to automatic tracking.