Don't have one? Create one ↗
← All courses

Lesson 10 of 17

SPA Virtual Pageviews

① Connect your GTM container

Paste your container ID to load it into this page. It only ever runs here.

Advanced: use a specific environment

A single-page app swaps views without ever reloading the browser. It rewrites the URL with history.pushState, so the classic Page View trigger, which only fires on a real page load, never sees the second, third or fourth screen. Your analytics would record one pageview for an entire session.

GTM solves this with the History Change trigger. It listens for pushState, hashchange and the back and forward buttons, then fires a virtual page_view tag for each, so an SPA gets counted like a normal multi-page site.

Goal

Fire a virtual page_view tag on every in-app navigation using a History Change trigger.

Build it in GTM

  1. Create the History Change trigger

    Go to Triggers → New and choose History Change. Leave it on All History Changes so it fires on every pushState, hash change and back/forward. This is what replaces the Page View trigger inside an SPA.
  2. Read the new Page Path

    The built-in Page Path variable already reflects the URL after each history change, so enable it under Variables → Configure if it is off. You will send this with your tag so each virtual pageview records the view the user landed on.
  3. Fire a virtual page_view tag on it

    Create your tag and set the History Change trigger as its firing trigger. On a real site this is a GA4 Event tag with event name page_view, sending the new Page Path. Here a Custom HTML tag named Custom HTML - Test containing <script></script> is a fine stand-in.

Debug in Tag Assistant

Copy this lesson's live URL and paste it into GTM Preview, that is the page Tag Assistant connects to. It has the clickable elements, so this page stays clean for reading.

  1. In your GTM, click Preview.
  2. Paste the live URL above and click Connect.
  3. Interact with the live page and watch your tag fire in Tag Assistant.

What you should expect to see

Click between the views and watch the left rail of Tag Assistant: each navigation adds a History event (gtm.historyChange), and your virtual page_view tag appears under Tags Fired on every one, with the new Page Path attached.

Verify your container

Built it? Export your container, Admin → Export Container, choose your workspace, then drop the JSON here to check it against this lesson.

Drop your container .json here

or browse · checked in your browser, nothing is uploaded

0 of 17 lessons complete