Track a single-page app
React, Vue, Svelte and other sites that change pages without a full reload work with the same line. Here's what Crustat sees.
No extra code needed
Some sites change pages without loading a whole new page: the address changes, but the browser never reloads. React, Vue, Svelte and Angular apps often work this way, and so do Astro’s view transitions and Next.js.
The same tracking line covers these sites. There’s no router setup, no hook to call and no event to send by hand. If you haven’t added the line yet, see Add Crustat to your website. For framework packages, see Astro and Next.js.
How Crustat notices a new page
Browsers tell scripts about these page changes in two ways: history.pushState, which your app’s router calls when someone clicks a link, and the popstate event, which fires on the back and forward buttons. Crustat listens for both.
Each time, it checks whether the page’s path or query changed. The path is the part after the domain, like /pricing. The query is the part after a ?, like ?page=2. If either changed, it records a new page view. If not, it does nothing.
That means these don’t create extra page views:
- Jumping to a section on the same page, like
#features. - A router repeating the same address, which some frameworks do as a side effect.
What happens on each page change
When the visitor moves to another page inside your app, three things happen:
- The time on the page they’re leaving is sent, just like when someone closes a tab. That keeps time on page and Session time right.
- A page view for the new page is recorded, along with the page it came from on your site. Crustat uses that to know this isn’t a new arrival, and to build visitor paths. Your own site never shows up as a referrer.
- Events set up on the Events tab start over for the new page. A scroll, time or page event can happen again on each page, just as on a site with full page loads. See Track clicks, forms and sales.
Two things Crustat doesn’t follow
- Hash routers. Some apps keep the page in the part after a
#, likeexample.com/#/about. Crustat only looks at the path and the query, so an app like this shows up as a single page. Most routers can switch to normal addresses (often called “history mode” or “browser router”); after that, every page shows up. history.replaceState. This swaps the current address without adding a step to the browser’s history. Crustat ignores it, so a router that changes pages this way won’t create page views. Routers normally use it only to tidy the address, not to move between pages.
Checking it works
Open your site in a normal browser window (not on localhost, which is skipped), click through a few pages, and wait about a minute. Each page you opened should appear under Pages on your dashboard.
Still stuck? Write to hello@crustat.com.