9am-6pm Mon-Fri

Tracking Virtual Pageviews in Google Tag Manager

Posted in: Marketing Started by

Tracking Virtual Pageviews in Google Tag Manager

Why Do We Need Virtual Pageviews?

“Real” pageviews are easy to understand. When someone visits a page on your site, that’s a pageview. The tracking javascript loads on the page and clocks a single view in Google Analytics.

However, not all website interactions are as straightforward as this. There are tons of things we want to track users doing on webpages that don’t cause the page to reload.

What is a Virtual Pageview?

A virtual pageview isn’t really a pageview at all, it’s a complete lie. But virtual pageviews are user actions that feel like real pageviews so they are tracked in the same way. This is usually to make website reporting easier by allowing pageviews, and actions that feel like pageviews to be categorised together.

The most popular example of a virtual pageview is downloading a PDF document. It can also be used for an overlay / lightbox impression on a website that requests a user’s details.

Event Tracking

Events are another way of tracking user behaviour on a website. Event Tracking is a core behavioural feature in Google Analytics. It allows you to categorise specific behaviours and get really granular with website tracking.

Users often hover over website elements to display flyout menus and click to expand to show more content. Neither of these actions could be classed as a virtual pageview, as they are minor or partial page interactions.

Similarly, actions like downloading a PDF doesn’t lend itself so well to being tracked as an event. A user is visiting a document on a website, so logging that as a URL visit means you can report on traffic, advanced segments, sources etc in the same way you do your HTML pages.

It makes things a bit simpler to use different tracking methods in different scenarios, but there are no fixed rules.

Google Tag Manager V2 (released October 2014)

GTM v1 vs. v2

Google made a major release to Google Tag Manager (GTM) in October 2014 that affected the UI. Google also renamed “macros” to “variables” and “rules” to “triggers”.

The changes were a bit of a slap in the face to early adopters of GTM, who were required to migrate their v1 tracking to v2. But they were rewarded with greater GTM functionality, and a more logical, powerful UI.

Tutorial – Tracking Virtual Pageviews in Google Tag Manager v2

For this worked example, we’re tracking impressions of a simple overlay on our website. You’ve probably seen it already if you’ve read this far:


The important thing to note is that this overlay is triggered by a timer on the website, currently set to 5500ms after the page load. If you’re tracking virtual pageviews based on user-fired events such as clicks or form submissions then Google Tag Manager already gives you the functionality that you need in its built in triggers.

Why not just use a GTM timer trigger?

We could use a GTM timer trigger, that fires an event after 5500ms to log that the overlay will have appeared. This is a really brittle and inflexible way of tracking. If the timer on the overlay was changed, then the tracking would be out of sync with what the user is actually seeing. Also if the overlay was disabled, then the GTM timer trigger would continue to fire. Again this misrepresents what the user is seeing. Where possible, your tracking should change automatically as you change features on the website.

Step 1: Get Set Up With Google Tag Manager

You’re probably already set up with GTM if you’re looking at virtual pageviews. Still, if you aren’t set up then go to tagmanager.google.com and follow the steps. There are a ton of online resources for getting the basics set up.

When you log into your GTM account, you’ll see the a list of containers:


Selecting a container will give you the dashboard where the magic happens:


Step 2: Start With The Data

I’d always recommend starting on the lowest possible level when implementing tracking. If you understand the data and code then everything else will play out from there. It’s just as possible to start at a high level on the tracking side.

As the overlay pops up after a timer on the website, we need to plug this event manually into the GTM Data Layer. By this we mean that when the overlay appears, we want to run some javascript that kicks some data over to Google Tag Manager that gets logged in Google Analytics. Simple right?

A pageview (virtual or real) is composed of a Page URL and a Page Title. You don’t have to include Page Title if you don’t want, but it’s an available slot for you to record data in so see it as an opportunity! You can see URL and Title as the two primary dimensions for pages in Google Analytics:



This javascript needs to run when the overlay appears. Depending on your implementation, this could be a topic for another blog post. On this site we used popup-maker and MailChimp for the forms and email subscription process:

<script type="text/javascript">
      'virtualPageTitle':'Want To Get Ahead In ECommerce Strategy'

Putting this code on the page won’t do anything as GTM needs to be configured to listen to the event.

Javascript explanations

Here’s a line by line breakdown of what the Javascript is doing:

  • dataLayer.push : This is a command recognised by GTM that will cause it to log the data passed to it.
  • event : This variable is the binding point between the Javascript and it being logged in GTM. More on this later. You can call it what you want.
  • virtualPageUrl : Set the relative URL that you want to log in GA.
  • virtualPageTitle : Set the page title that you want to log in GA.

Step 3: Set up GTM Data Layer Variables

Now you’ve got your javascript code in place, it’s time to start wiring it up to Google Tag Manager.

The two variables in the Javascript that actually contain the page data (virtualPageUrl & virtualPageTitle) need to be set up in GTM as data layer variables.

Go to Variables -> User Defined Variables -> New


Set up a variable for virtualPageURL:


Set up a variable for virtualPageTitle:


You should now see both variables listed in the variables dashboard:


We’ve now got the data part of our tracking mechanism in place, as data from the website will now be held in GTM variables.

Step 4: Set Up GTM Virtual Pageview Trigger

Next we have to configure our GTM triggering logic to actually capture the data.

Remember our Javascript code earlier? We want GTM to “listen” to the value of “event” being “VirtualPageview”. See in bold below:

<script type="text/javascript">
      'virtualPageTitle':'Want To Get Ahead In ECommerce Strategy'

Go to Triggers -> New

Create a Virtual Pageview trigger as a Custom Event.


Step 5: Set Up GTM Virtual Pageview Tag

So now we have our website passing page data (step 1) to GTM variables (Step 2) and a trigger in place for GTM to do something with the data when it hears that a virtual pageview has happened (step 3).

Now we need to configure a GTM tag, which is the link between GTM and Google Analytics so that the data can actually be logged. GTM plugs into a range of different tracking platforms, so you have to specify at this point that you want it to go to your GA account.

Go to Tags -> New




  • Choose Product: Select Google Analytics
  • Choose a Tag Type: Select Universal Analytics (or Classic if you’re still using it)
  • Configure Tag:
    • Insert your GA linking information (Tracking id)
    • Track Type: Page View
    • More settings -> Fields to set
      • page : {{virtualPageUrl}}
      • title: {{virtualPageTitle}}
  • Fire On: Select “Virtual Page View Trigger”


Some things to note!

“The fields to set” are the variables from the Javascript. These bind the data from the webpage to the reserved fields in Google Analytics for what a Pageview really is. You can see a full list of these reserved fields here.

In v1 of Google Tag Manager, these were set differently in the UI to how it’s now done in v2.

Step 6: Debug and Publish

The debugging features in GTM are pretty awesome. Debugging tracking issues historically is really complex, especially if you’ve inherited a badly-managed system.

Go to Publish -> Preview and Debug -> Preview


Now when you visit the page which triggers the overlay in the same browser, you’ll get the debug panel which will show you what’s happening behind the scenes.

You should see the Trigger we set up earlier firing under the “tags” tab:


You’ll also see the values of the javascript variables we set up for the title and the url being passed into GTM:


And for a summary of the whole snippet that’s being passed to the Data Layer:


If you’re not seeing the data in the above images, check your spelling of the javascript and GTM variables. Typos will cause them to not link up correctly – look for case-sensitive issues.

Step 7: Publish and Check Google Analytics

Go to the realtime dashboard in Google Analytics and you’ll be able to see “visits” to the virtual page appearing showing the URL and title:


And after a few hours, you’ll be able to see them in your GA page reports. Note how entrances will always be zero, as a user will have to make a real pageview before they will get this virtual pageview:


Step 8: Let us know your thoughts!

I hope this post was of use in explaining how to configure virtual pageviews in GTM v2. Once you’ve set up website tracking, it might be time to audit your website’s technical SEO, or take your pick from one of these SEO audit tools that we reviewed.

If you need a hand with your company’s website tracking and Google Analytics please post a question in the comments below or contact us.


And here are some great resources for learning more about Google Analytics:



  1. Lars Bo Jensen Reply

    Thank you for posting this! The world needs it. I need it. I am new to GTM and partly to the more advanced parts of GA. Your article makes some things clear, and I have got just one question: Must I add javascript to the code (and do the dataLayer.push) if I want to set this up? I want to get virtual pageviews from a page with a self-referring form. I thought that I could somehow give GTM the ID of the form or button and that it could be set up without adding code on the website.

    • George Harris Reply

      Thanks for the feedback Lars!

      Just to clear this question up for any other readers (as conversation moved to Google+).

      GTM has built in triggers and variables for tracking form submissions already, so when you create your tag you can just use these to track what you want.

  2. Anshul Reply

    Thanks, this really helped me a lot. I was new to gtm and was really struallggling with my hash routes analytics. Really appreciate the in-depth explanation.

    • George Harris Reply

      Hi Anshul, thanks for reading and glad you found it useful!


  3. Jack Reply

    Hi, Thanks for your valuable article. We need to publish the version before preview and debug? While I’m open my page as preview and debug it displays as “Tags Not Fired On This Page” in the footer.

    • George Harris Reply

      Hi, You should be able to preview and debug before publishing (as that’s the main point of this feature :)).

      It sounds as though your triggers aren’t firing on the criteria you’ve set – so worth double-checking they’re set up correctly. You can use the debug panel in the browser to dig deeper into the issue.

  4. Ben Reply

    Hi, will the original URL be tracked in addition to the virtual pageview URL?

    • George Harris Reply

      Hi Ben,

      A “virtual” pageview is tracked as a pageview in GA. You’ll be able to look at the user journey as you normally would if a user was browsing between pages on your site.

      What you’re referring to sounds like it might be better achieved using Events. You would then be able to look on which pages an event was fired.

      • Ben Reply

        Hi George, thanks for getting back to me.

        What I was referring to is the URL displayed in the browser still tracked as a pageview when your virtual pageview code is fired. Or will the code that fires the virtual pageview cancel that browser URL pageview tracking with GA. Just wondering if we have to deal with the same page being tracked as 1 or 2 views in GA.

        • George Harris Reply

          Hi Ben,

          Say if you visit /page1 on your website and there’s a link on there to download a PDF which is set up to track as a virtual pageview as /Pdf-doc.

          Visiting /page1 will track an ordinary pageview in GA as standard.

          If you click on the link to download the PDF, then just that /pdf-doc virtual pageview is logged to GA.

          So in this example 2 pageviews are tracked in GA just once.

          Hope that helps.

          • Ben

            Thanks George, that is very helpful

  5. Francis Magos Reply

    Hi George,

    Good job in having this instructions for setting up a Google Tag Manager for us to track the virtual pageviews. I have a question though, I have a website that caters 20+ different modes of payment like quick transfers, paypal, etc., which I setup a virtual pageview for me to track conversions on GA, is this also possible between Google Tag Manager and virtual Pageviews providing more I have more than 20 target goal conversion that I can setup for tracking?

    • George Harris Reply

      Hi Francis,

      I wouldn’t recommend using virtual page views for tracking e-commerce transactions as GA already offers e-commerce tracking which is far more suitable as it’ll allow you to capture more data.

      Is there a reason you’re looking to use virtual page views for this?

      • Francis Magos Reply

        There are different payment/deposit forms that I have in my website and I am not using an E-Commerce platform. I just want to setup a GTM, firing a virtual pageview on Submit buttons.

        Is this possible, George?

        • George Harris Reply

          Personally I wouldn’t use virtual pageviews for this. I would use E-Commerce tracking as this is what it’s designed for. You don’t need to use an E-Commerce platform to do it, but you will need to write some Javascript to wire it up (in the same way you’d have to for virtual pageviews).

          I recommend starting here: https://support.google.com/analytics/answer/1009612?hl=en

          And some more on E-Commerce tracking: https://support.google.com/tagmanager/answer/6107169

          It’s worth the effort as then all your sales / transaction data will be nicely logged in Google Analytics.

          Hope that helps.

  6. Sharon Reply

    It looks like to collect a virtual page view, the URL has to change? What if the URL does not change, e.g., a modal pops up over the current home page. I would like to tag the modal as a virtual page view, but there is no URL or page title change. How would I: 1) tag and track the modal; 2) name the modal – would it be a manual input under page URL, e.g., homepage/modal (but there is no URL change, it is still http://www.homepage).

    • George Harris Reply

      Hi Sharon,

      To track a virtual pageview, you set the URL / title yourself.

      So for the virtualPageURL variable in the article above you might set it as “/modal/homepage/”.

      Then you can report on it as you would do a normal page view in Analytics.


  7. Craig Pence Reply

    Hi George,

    Thanks for writing this article! I was hoping you could help me out a bit more with my particular situation.

    On the page below when you click the Brochure button, the window gets displayed via an AJAX lightbox. My goal is to track once someone clicks the orange “DOWNLOAD BROCHURE” button….


    I’ve read a lot of documentation but am still not sure how to properly set it up and if it requires additional code be added to the frame.

    Thank you!

    • George Harris Reply

      Hi Craig,

      In theory you should just be able to wire up a click event via GTM for the button id “btn_signup_brochure”.

      If you’re not using GTM, it doesn’t work or aren’t familiar with it, you could just add inline JS to fire the GA Event when someone clicks the button onclick. You then wire this event up to a Goal in GA if you want to track it as a conversion.

      Hope that helps.

      • Craig Pence Reply

        Hey George,

        I am doing it via GTM but when I’m in preview and debug and I click the DOWNLOAD BROCHURE button while in the lightbox, there is no gtm.click event showing up on the left hand side of the GTM preview and debug console under “Summary”. However, the odd thing is that when I click the x to close the lightbox it does send a gtm.click event with click class = ‘mfp-close’

        Now I’m totally confused lol

        • George Harris Reply

          Ah that’s probably because it’s a Form Submission, which is a different type of trigger to a click.

          Try that instead.

          • Craig Pence

            Ok sounds good, thanks George

  8. Alex Reply


    Fantastic article – thanks so much. I’m not a dev but have the task of setting up GA & GTM for our single page application so this is probably a fairly basic q – where exactly would the datalayer.push code go on the page? Before the GTM code or after? None of our devs are front-end or javascript proficient so I need to give them very specific instructions!

    Cheers 🙂

    • George Harris Reply

      Thanks for reading, Alex. Your devs probably need to learn JavaScript :). Data Layer initialisations should come before the container code in the page head.

      It’s explained here: “If the data layer code is called after the container snippet, any variables declared within will not be available for Google Tag Manager to selectively fire tags on page load”


  9. Sergey Reply

    Hi George,

    Thanks for great post!

    I have one problem: all virtualPageViews not shown inside Analytics panel. I checked site with GTM tools and variables filled correctly. What am I missing for ?

    P.S. I try to test on localhost.

    • George Harris Reply

      Hi Sergey,

      The best way to debug this is to look at the javascript calls to GA in the “network” panel in developer tools in the browser. You should see an Event call to GA with the Event Category, Action etc set if it’s working.

      Perhaps your datalayer event trigger isn’t firing due to a typo mismatch between your javascript and your custom event trigger (check casing). Therefore the Event tag isn’t firing and registering in GA.

      If you DO see the event call firing to GA in network requests, then check you haven’t got a filter in GA blocking the domain you’re testing from.


        • George Harris Reply

          It’s in Admin -> all filters (at the account level) or at the view level.

          Are normal pageviews / events tracking to GA? If so it’s probably something else.

          I take it you’ve double checked the UA tracking code. Does the call to GA return an HTTP 200?

          • Sergey

            I found reason why it didn’t work.

            When I changed Google Analytics web-site settings from “mydomain.com” to “” – I see all page views there. I am still tesing on localhost.

            Maybe it will be useful for someone.

  10. Prabhu Reply


    I need to track more than 3 types of virtual page views for product1, product2, product3 all are dynamic URL’s. So, I am using regular expression in analytics. My question here is, should I have the different custom event name for each product or using the same custom event name I can capture all the virtual page views?

    • George Harris Reply


      You can use the same custom data layer event name, and vary the virtual page url passed in the other variable. Then in GTM, when your virtual pageview tag fires (based on the event name) the correct url is then passed to GA via the variable.

      Equally it would work with a different event / tag for each page view and you can hardcode the URL in GTM. It’s whatever you find easiest to manage.


      • Prabhu Reply

        Hi George,

        You meant to say, by using the same custom event name, just vary the virtual page url in the data layer for all the 3 products?

        • George Harris Reply

          Yes sir.

          Set virtualPageURL and title to whatever you want, GTM just feeds them through to GA.

          • Prabhu

            Thanks George, hope it will help me.

  11. A Reply

    Hi George,

    This is a great article.

    Will these Event based VPV’s work when setting up a funnel or is should the javascript be based OnClick?



    • George Harris Reply

      Hi, Thanks for reading.

      The VPV set up as a Pageview in GTM needs a trigger of some sort. In the case of the article there’s no OnClick as the overlay appears after a period of time and isn’t triggered by the user. The event push to the DataLayer happens as the JS is rendered inside the overlay. You could just as easily use an onclick for VPVs that are fired by a user interaction. e.g. a user doing a postcode lookup in E-Commerce checkout. If the funnelling you’re referring to is in GA Goals, then yes you have to use pageviews (or VPVs) as GA doesn’t support funnels for events. GA doesn’t care how the VPVs are triggered in GTM though, so long as it receives a pageview.


  12. Young Reply

    Hi George,

    Thanks for great post.

    I’d like to use GTM to do page view track when a modal window pops up in our single page application(angular application).
    Must I add the datalayer.push code on my webpage manually?
    I don’t want to modify sources of our webpages except installing Google Tag Manager.
    Is it possible?


    • George Harris Reply

      Hi Young,

      Yes it’s possible without using the data layer, but definitely not as good. The main issue you have is that you need a trigger to fire the Virtual PageView tag. Usually triggers are fired by users by clicking / scrolling etc. For a Modal/Lightbox window, the trigger is usually decided by the website (e.g. after 10 seconds, or at a certain scroll position).

      Assuming the modal is triggered by a timer, you could just create a GTM Timer trigger to fire the VPV. If it’s triggered by scrolling down the page you could use a GTM Scroll Trigger. You would hardcode the Page URL and (optionally) Title in the PageView Tag.

      The main reason why this isn’t as good is if your Modal trigger is edited (e.g. to 20 seconds), then you have to update the GTM trigger as well. Also, if you have lots of different Modals then managing how these are logged in GA becomes a bit more complicated as you need to detect which modal has fired.

      Hope that helps,


      • Young Reply

        Thank you for your help.

        By the way, I’m wondering if GTM can track keystrokes (especially, without modifying the webpages sources)? For example, want to know if the clients press “Enter” key .


        • George Harris Reply

          To track keystrokes specifically you will definitely need to use some custom Javascript. It shouldn’t be that difficult. If pressing “ENTER” causes some kind of action to happen on the site (e.g. Form Submission) then you can track that action more easily than trying to hook into the keystroke.

          • Young

            It helps me a lot, I’ll try it out.
            Thank you very much again.

      • Young Reply

        Hi George,

        I have another question about data layer. Could I use GTM to add that data layer snippet to my webpage? That is, I’m not allowed to modify the source of that webpage.
        So I’m wondering if GTM can manage all data layer snippets via GTM user interface, instead of hard coding on my webpages manually with the help of frontend developers.


        • George Harris Reply

          Yes you can do this using a script snippet inside a custom HTML tag (fired on the pages you need it on). I would think carefully beforehand though as to whether it’s really necessary. You still have the same challenge wiring up the trigger and extracting the data that’s relevant to your tracking.

          • Young

            Thank you for your advice.
            You’re the most patient writer I’ve encountered.
            Thank you veeeeeeeeeeeeeeery much.

          • George Harris

            you’re welcome 🙂

  13. Dave Reply

    Thank you very much for this article. It details the steps very thoroughly and has really helped me.

    • George Harris Reply

      Great to hear! Thanks for the comment, Dave.

  14. Caio Vinícius Serra Reply


    Thank you very much for the explanations.
    I was struggling a long time how to send virtual events, pageview, and eCommerce tags via jQuery selectors.
    When I was not using GTM, the triggers were working perfectly. Since I implemented GTM, I had to create tag by tag in GTM cause my js selectors stopped to work.
    Just saved me some hours of work!

    Thanks a lot!
    Caio Serra

Leave a Reply