Virtual 404 Pageviews for Google Analytics in ExpressionEngine
Ryan Masuga

Virtual 404 Pageviews for Google Analytics in ExpressionEngine

February 16, 2016 by Ryan Masuga

One of the first things I do when looking at a site is type a bunch of junk in the URL to get a 404 page (OK, so I have some weird hobbies). Many sites have interesting or funny 404 pages. There are listicles and websites devoted to clever 404 pages.

As funny or interesting as 404 pages can be, we ultimately want them to be helpful if someone does find their way there, and we want visitors to see these error pages as little as possible.

When you’re converting a site from another CMS or changing around URL structure, you’re probably going to miss out on more than a few 301 redirects, so a decent, helpful error page in place is a real advantage. But how can we easily know when this page is being hit, and from where? It's easy when we use Virtual Pageviews in Google Analytics.

There are a lot of advanced uses for virtual pageviews, but this one is relatively simple: we're just sending some extra information about the page the user was trying to reach, and from where they came.

This should be added to your 404 page, but not the other pages of your site.

Adding the Code In ExpressionEngine

Here's how we do this in ExpressionEngine, using layout variables. In our main layout, we have our Google Analytics code just before the closing </head> tag (using the traditional asynchronous tracking snippet). Note the ExpressionEngine conditional for “ga_pageview” in there:

<script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-12345678-9']);
  {if layout:ga_pageview != ''}{layout:ga_pageview}{if:else}_gaq.push(['_trackPageview']);{/if}
  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);

There is also the Universal Analytics tracking code, and in that case our nearly identical conditional is positioned towards the bottom:

(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),

ga('create', 'UA-12345678-9', 'auto');
{if layout:ga_pageview != ''}{layout:ga_pageview}{if:else}ga('send', 'pageview');{/if}


Then, in our 404 template we set the ga_pageview variable:

{layout:set name="ga_pageview"}_gaq.push(['_trackPageview','/404/?url=' + document.location.pathname + + '&ref=' + document.referrer]);{/layout:set}

This layout variable is passed to our layout to override the default ga_pageview there. We create a "virtual" 404 and append the information we want to track.

Viewing the "404" Pages in Google Analytics

You can see that each "page" contains the requested URL and the referrer (if any).

Viewing our 404 virtual pageviews in Google Analytics

An example of 404 pages in Google Analytics from Based on this, we should add a 301 redirect for those pages that lived at “/the-lab/scripts,” and probably help people who are trying to hit that old download link, too.

All we need to do now is filter for "404" in Google Analytics to see our virtual pageviews.

We haven't had occasion to do this for 404 pages with Google Tag Manager yet, but there are resources out there that explain how to do this.

I wrote about this method (as well as a lot more tips and tricks for ExpressionEngine) in my book The Guide to ExpressionEngine Development.

You Might Also Like