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 your grasp of SPA routing mechanics. A great answer covers both programmatic navigation (using router hooks) and browser history events (popstate), explaining why both are necessary.

What's really being asked

This question tests your understanding of how Single Page Applications manage navigation state without full page reloads. The interviewer wants to see if you know the underlying browser mechanism—the History API—that frameworks like React Router and Vue Router abstract away. They are assessing your ability to hook into the SPA lifecycle at the right points to capture meaningful user actions, differentiating between user-initiated navigation within the app and browser-level actions like using the back/forward buttons.

The full answer

A strong answer addresses two distinct navigation scenarios. First, for programmatic navigation (e.g., clicking a <Link> component), you should hook into your framework's router. In React, this is typically a useEffect hook that depends on the location object from react-router-dom. When location.pathname changes, you fire your tracking event. Second, for browser-driven navigation (back/forward buttons), you must listen for the popstate event on the window object. This is crucial because the History API methods pushState and replaceState, which routers use internally, do not trigger a popstate event themselves. A complete solution requires both.

The mistakes people make

A major red flag is providing an incomplete solution, like only mentioning the useEffect hook and forgetting about the popstate event for browser history navigation. This signals a framework-level understanding without knowledge of the underlying browser APIs. Another common mistake is incorrectly stating that pushState or replaceState fires an event. Candidates also fail by giving a vague answer like "I'd use an analytics library" without explaining how that library would detect the navigation change, which is the core of the question.

What usually comes next

Expect questions about implementation details. "How would you avoid sending duplicate events if both your effect hook and popstate listener fire close together?" (Debouncing or state management). "What other information would you send with a page view event?" (User ID, session ID, referrer URL, time since last event). "How does this change if the app uses hash-based routing (/#/about)?" (You'd listen for the hashchange event instead of popstate).

A concrete example

In a React app using React Router, you'd create a component that runs on every page. It would contain two useEffect hooks. The first hook would be: useEffect(() => { trackPageView(location.pathname); }, [location.pathname]);. This handles internal navigation. The second hook would be: useEffect(() => { const handlePopState = () => trackPageView(window.location.pathname); window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, []);. This handles back/forward clicks.

Interview question

What is the most comprehensive approach to accurately track page views in a Single Page Application (SPA)?

  • a.Implement both framework-specific router hooks for internal navigation and a window.popstate listener for browser back/forward actions.Correct
  • b.Use a router hook (e.g., React's useEffect on location.pathname) to trigger a page view event when the URL changes.
  • c.Configure an analytics library to automatically track page views, as it inherently understands SPA routing mechanisms.
  • d.Attach an event listener to the window object for the popstate event to capture all URL changes initiated by the user.
Why?

A complete solution for tracking SPA page views requires handling two distinct scenarios: programmatic navigation (e.g., clicking internal links) via framework router hooks, and browser-driven navigation (e.g., back/forward buttons) via the window.popstate event. Option D is a tempting distractor because while popstate is crucial for browser history buttons, it does not fire for programmatic navigation using pushState or replaceState, making it an incomplete solution.

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 spa — each one lists the topics its interview covers.

See open roles