Tracking

Track a single-page application

Single-page applications (SPAs) built with React, Next.js, Vue, Nuxt, Angular, and similar frameworks work with Umami out of the box. The tracker script automatically detects client-side navigation and records page views without any extra configuration.

Basic setup#

Add the Umami tracker script to your application's <head> just like any other website. The script handles both traditional page loads and client-side route changes.

Next.js (App Router)#

Add the script to your root layout:

Alternatively, use the Next.js Script component:

React (Vite / Create React App)#

Add the script tag to your index.html:

Vue / Nuxt#

For Nuxt, add it to nuxt.config.ts:

For plain Vue with Vite, add the script to index.html just like React.

Angular#

Add the script to src/index.html:

How it works#

Umami's tracker script monitors the browser's History API (pushState and replaceState) and the popstate event. When your SPA navigates to a new route, Umami automatically sends a page view with the updated URL and title.

This means you do not need to manually call umami.track() for page views in most cases.

Tracking custom events in components#

To track button clicks or other interactions within your components, use the data attributes approach or call umami.track() directly:

Or with JavaScript:

Troubleshooting
  • Pages not tracked after navigation: Make sure the tracker script is loaded once in the root layout, not re-added on every route change.
  • Duplicate page views: Avoid calling umami.track() without arguments in useEffect or onMounted hooks, since the tracker already records navigation automatically.
  • Hash-based routing: If your app uses hash routing (/#/page), Umami tracks these by default. You can disable hash collection with data-exclude-hash="true" if needed.