Skip to content
tezvyn:

How do you track page views in a Single Page Application?

Source: developer.mozilla.orgMediumHow cards are made

How do you track page views in a Single Page Application?

This tests SPA analytics beyond classic page loads. A strong answer covers History API pushState and popstate events, framework router hooks like useEffect or afterEach, and beaconing views. A red flag is relying only on window.load or polling URL changes.

What's really being asked

This question probes whether you recognize that Single Page Applications do not trigger traditional page load events after the initial render, so standard analytics snippets that rely on window load or DOMContentLoaded will miss most user journeys. Interviewers want to see that you understand the difference between browser-level navigation and client-side routing, and that you can instrument the correct lifecycle points to capture meaningful page view events without breaking the user experience or duplicating metrics.

The full answer

A strong response should hit four things in order. First, name the History API as the browser primitive that enables SPAs to modify session history without reloading, specifically calling out pushState and replaceState as the methods that add or update history entries, and the popstate event as the signal fired when the user navigates back or forward. Second, explain that modern frameworks abstract this away, so in React you would likely use a useEffect in the router component or listen to history changes from React Router, while in Vue you would use Vue Router afterEach navigation guards. Third, describe the actual tracking mechanism, such as calling gtag or sending a beacon via navigator.sendBeacon or fetch to your analytics endpoint with the current route and metadata. Fourth, mention deduplication and initialization, ensuring the initial page load is tracked once and subsequent route changes do not double count.

The mistakes people make

The biggest red flag is suggesting you can just listen to window.onload or setInterval polling on location.href, because these miss programmatic navigation and create race conditions. Another weak pattern is proposing to instrument every button click instead of the router layer, which is fragile and misses back or forward button usage. Finally, failing to mention that pushState itself does not fire an event, so you must wrap or observe the calls, indicates a shallow understanding of the History API.

What usually comes next

An interviewer might ask how you would handle hash-based routing versus history-based routing, or how to track dynamic route parameters like product IDs. They may also ask about performance implications of firing analytics synchronously versus using sendBeacon for unload scenarios, or how to correlate page views with user sessions in a stateful SPA.

A concrete example

Suppose you are using React Router v6. You could create a custom Analytics component that uses useLocation inside a useEffect. Whenever the pathname changes, you call window.gtag config with the new page_path. You also need a separate useEffect on mount to handle the initial landing, because the first page does not trigger a navigation event. If the user clicks the back button, the browser fires popstate, which React Router handles and updates useLocation, so your effect fires again and logs the restored page.

Interview question

Which strategy reliably tracks all page views in a React Router SPA without missing programmatic navigation or back-button usage?

  • a.Listen to window.onload and DOMContentLoaded to catch every route change.
  • b.Poll location.href with setInterval to detect URL changes continuously.
  • c.Use a router hook like useLocation in useEffect, and also handle the initial landing separately.Correct
  • d.Attach click event listeners to every navigation link and button in the application.
Why?

Router hooks like useLocation capture both programmatic navigation and popstate-driven back/forward changes, while listening to window.onload fails because client-side routing never reloads the page after the initial render.

Just read this? Test yourself on what you have been reading.

Read the original → developer.mozilla.org

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on analytics — each one lists the topics its interview covers.

See open roles