How To Fire A Virtual Pageview In Google Tag Manager

September 10, 2014
By Sayf Sharif


Firing a Google Analytics Virtual Pageview with Google Tag Manager is easy, and far more powerful than ever before.

When our clients or training attendees upgrade from classic Google Analytics to Universal Analytics implemented through Google Tag Manager, we often get questions about how to transition these Virtual Pageviews from inline code to being implemented through GTM.

There are a number of different ways you can implement Virtual Pageviews, and hopefully this will provide one solution to help ease the transition to a GTM implementation of Google Analytics.

What Is a Virtual Pageview

Virtual Pageviews, for those not in the know, are when we send page hits to Google Analytics, without reloading the page. A standard page hit occurs when Google Analytics loads on a page. Sometimes though we want to fire ANOTHER page hit without actually going to another page, or reloading the page itself.

There are various reasons you would want to do this:

  • A contact form that submits dynamically to itself without reloading the page
  • Tracking downloads of PDF files on your site as pages
  • Modal popup windows of images, or with information capture forms
  • Multi-step dynamic shopping cart pages

For these concepts and more, Virtual Pageviews are the answer to your problem. You can fire a Pageview just as if the page was loaded, and Google Analytics will treat it as just another page hit on the site, allowing the use of URL Destination goals, Goal Funnels, and more.

How Was It Fired Before

Prior to Google Tag Manager a Virtual Pageview was fired in primarily one of two ways. Either within a script, or inline. When it was within JavaScript you could include a line like below inside any other code, and as long as Google Analytics was loaded on the page, it would fire a Pageview hit.

Classic Google Analytics Example:

_gaq.push(['_trackPageview', '/downloads/pdfs/corporateBrief.pdf']);

Universal Analytics Example:

ga('send', 'pageview', 'page path');

This code could also be placed “inline” on elements on a page, such as within the HTML code for a link, so that when someone clicked a link, certain JavaScript within the link itself would fire. This has been fairly common, but it’s prone to human error, with sometimes hundreds of links manually tagged.

Implementing or changing any of these Virtual Pageviews could be difficult, and require developer resources and time that simply didn’t exist.

How Can We Fire a Virtual Pageview With Google Tag Manager

First obviously, you need to install Google Tag Manager on your website.

If you are able to access the code of the website, it can be relatively easy to swap code. Instead of the above code snippets, we are going to do a dataLayer.push that looks like this:

'virtualPageTitle' : 'Order Step 1 – Contact Information'

The dataLayer is an object that Google Tag Manager reads on the page, and it lets us send instructions to Google Tag Manager. In this case we’re saying “An event named ‘VirtualPageview’ is occuring. The value of virtualPageURL is ‘/order/step1/ and the value of ‘virtualPageTitle’ is ‘Order Step 1 – Contact Information“.

Obviously this would change depending on what fake virtual URL or title you wanted to have sent to Google Analytics. This code can be put inline, or can be put into a JavaScript function anywhere on the page, and when it runs, it will insert those instructions into the dataLayer which will be read and acted upon by Google Tag Manager.

Creating the Necessary Tags, Rules, and Macros

We could implement that code in 100 places though, and nothing would fire, because we still need to set it up in Google Tag Manager. That part is simple.

First create two macros, one for virtualPageURL and one for virtualPageTitle both as Data Layer Variable types.




Next create a rule for {{event}} containing VirtualPageview


Lastly create a Universal Analytics Pageview tag, that fires on the rule you created, and in its configuration under More Settings, and Basic Configuration, put the macro values you just created in place for Document Path, and Document Title.


Save and Preview/Debug!

Now when that code on the page fires, it will fire a Vitual Pageview with whatever values that dataLayer.push passes. Those hundreds of inline and script implementations will all fire off those 2 macros, 1 rule, and 1 tag.

But what if we can’t access the code, or don’t want to

Sometimes you actually can’t access the code and put those dataLayer.push lines in, or maybe you don’t even want to. How about our example of having thousands of pdf files that are on your site, and you want to track them all as a Virtual Pageview from within Google Tag Manager without modifying any of their links? No problem.

First, if you don’t already have one, create a Link Click Listener tag in Google Tag Manager and either put it on All Pages, or on the pages you want to track your PDFs.


Second, create a rule that fires when event contains gtm.linkClick (i.e. someone clicked on a link) and where {{element url}} matches the regular expression (regardless of case) for the PDF extension as shown in this screenshot. {{element url}} is a prebuilt macro that should already exist in your GTM and in this case, just pulls in the URL of the link that was clicked.


Third, create a tag that fires a Pageview on that rule, and replace the Document Path and Title in the Basic Configuration settings for that Pageview with the element url and title so that the URL of the Pageview is the PDF file location, and the title of the page view is the text in the link for the PDF.


As long as your developers have put Google Tag Manager on your site, you could have a million PDF downloads, and by adding a single rule and two tags you are now tracking all of them as Virtual Pageviews really in a matter of minutes.

What else? What if it’s a modal window and I’m not looking for a file extension?

You can look for some aspect of the link that causes the Virtual Pageview to happen. For instance, maybe you have a dynamic contact form, and it has a form that submits. Find the name of the form by looking at the source code of the page, for something like this:

<form id=”testForm”>

The form ID is a unique value that you can use to target that specific form. If you want to fire a Virtual Pageview when someone submits that form just do the following:

First, create a Form Submit Listener tag and put it on the page you want with a firing rule (I’m using All Pages).


Next make a new rule with the conditions of an event containing gtm.formSubmit (i.e. a form was submitted), as well as where {{element id}} contains (or equals) that ID value, which in this case is testForm.


Finally, make a new Pageview tag, and have it fire on the Form Submit rule you just made, where you specify the values of the Document Path and Title again.


Notice here how I put all of these Virtual Pageviews into their “directory.” This helps with clearly identifying Virtual Pageviews from regular Pageviews, and also makes it easier to filter these out of a view if needed.

It’s that easy. You can use the same techniques to essentially track the clicks of any element, link, or submission of any form on a page as a Virtual Pageview. Is there a button or link that sends the user to the next virtual step in your contact form? Do it on that. Does that link launch a lightbox window? Track it.


Tracking Virtual Pageviews with Google Tag Manager is a huge improvement on the old way of doing things. It’s easy, and with Google Tag Manager it’s fast. Your transition to a GTM and UA implemenation might actually be sped up using some of these tricks, and hopefully you’ll be encouraged to track more things on your page where before you may have hesitated because of the development cost.

And don’t forget…

Remember. You defense. Points come. Concentrate. Focus power. Remember balance. Make good fight.


You’re the best! AROUND! Nothing’s gonna ever keep you down!