Learning to Use Google Analytics More Effectively at CodePen

❥ Sponsor

Here’s how most people use Google Analytics: you copy and paste the default tracking snippet into your templates. Look at the pageview data that comes in. That’s all good, but that isn’t the most useful analytics for many sites. Google Analytics can track just about anything. It’s very flexible and very powerful. Philip Walton and I co-wrote this article to show you how to do some custom GA stuff to help you collect data you maybe didn’t know you could collect and how you can look at that data in useful ways.

The Beginning

It’s fairly obvious you need some kind of analytics for any web app. At the most basic level, you need to know how many people are using the app, and if that number is going up or down.

The choice at CodePen was Google Analytics, because most of the team had used it before. It was free and easy to install. The team did what most people do when installing Google Analytics: we copied and pasted the default tracking snippet and that’s it. Nothing custom at all.

Data started coming in, and after a few days there is a general sense of what pages people were visiting on CodePen.

The problem is CodePen isn’t a really a pageview-based site, like, say a publication is. What pages people visit tells doesn’t tell the story about how users interact with CodePen. Much more interesting is to know what people are doing on those pages so optimizations can be made to improve their experience.

Unfortunately, none of the team really knew how to use Google Analytics to get the variety of information needed, so for a long time nothing was done.

Long story short: Chris meets Philip at CSSDevConf last fall. Philip says a lot of developers are in the same position — not taking advantage of the free, powerful tool at their fingertips. Part of Philip’s job is to teach developers, so in an epic tornado of wins, they partnered up to do smarter stuff with analytics at CodePen and share that with everyone.

What CodePen Wanted To Get From Analytics

Analytics data itself is meaningless if you haven’t figured out what problems you’re trying to solve or what questions you’re trying to answer. CodePen created a list of questions they thought would be useful to them and that would answer real questions they have about usage of the app.

Here’s a few quickies:

  • How many users are logged in (as opposed to using the site logged out/anonymous)? Is there a way to report on just the interactions of logged in users?
  • Of logged in users, how many of them have PRO accounts? How are the interactions of PRO users different from non-PRO users?
  • How many of total users have been active recently? What is the MAU, as they say (Monthly Active Users)?
  • When users change the layout of the Editor, which do they prefer: top, left, or right?
  • When users heart a Pen, what view are they in? What about when they leave a comment? These actions can be done from multiple places.
  • When users click on links to other sites, where are they going?

Understanding How Google Analytics Works

There is a couple of key concepts that make understanding everything else about Google Analytics much more clear.

Everything stems from knowing how to send data to Google Analytics. Then later, knowing how to get that data back in a meaningful way.

Sending Data to Google Analytics

You can send pretty much anything you want!

The normal thing (that the default tracking snippet) sends is the pageview. All you’re really doing is sending an HTTP request with some key/value data encoded in the URL or POST body. The keys are things like the page title, like “Explore Pens on CodePen”.

With the default tracking snippet, you’ll see these two lines at the end:

ga('create', 'UA-XXXXX-Y', 'auto');
ga('send', 'pageview');

The first line creates a tracker object, which is really just a JavaScript object that stores the key/value data we talked about above. The second line sends that key/value data via an HTTP request to the Google Analytics account (technically the “Property“) specified by the “UA-XXXXX-Y” number used in the previous line.

Google Analytics receives these HTTP requests (known as “hits“) and processes them. Based on the data in each hit, as well as the time and order the hits were received, Google Analytics is able to organize the data into a hierarchy of Users, Sessions, and Interactions.

In CodePen terms:

  • A user is anyone who visits the CodePen site.
  • An interaction is something they do on the site (e.g. visit their profile page or click the “heart” button on a Pen).
  • A session is a group of interactions by the same user that occur within a certain amount of time. If a user logs in to CodePen, creates a Pen, and then leaves, that would be one session. If they came back a few hours later in the day, that would be a different session.

A user can have many sessions, and a session can have many interactions.

Reporting on Data

Once Google Analytics has organized your data into users, sessions and interactions, you can query that data and get back a report.

Google Analytics has a lot of built-in reports. You are not limited to just those reports.

In fact, arguably the best way to improve your effectiveness with Google Analytics is to learn how to create your own reports (called “Custom Reports“), so you can query for whatever data you want. If you’re sending Google Analytics custom data specific to your application, there’s no way you’ll be able to answer all your questions with just the built-in reports.

Every report (whether built-in or custom) in Google Analytics is the result of querying for a set of dimensions and metrics. Since creating a custom report requires specifying the dimensions and metrics yourself, it’s important to understand what those are.

Metrics are a quantitative measurement of data, like total number of pages visited (pageviews) or average time on site (Avg. Session Duration). Metrics are always numeric. They’re usually counts but they can also be averages or ratios.

Dimensions are cross sections of your metrics, they’re how you subdivide your data further, for example you might want to subdivide total pageviews by the page URL to see which pages are popular, or you might want to subdivide average time on site by the different browsers people use to see if there are any correlations there. In these cases, Page and Browser are the dimensions.

The data comes back as a table. The dimension values are usually in the columns on the left, and their corresponding metric values are in the columns on the right. You can optionally apply filters to conditionally exclude rows from the results.

An Example of a Custom Report

The table below is an example custom report that shows data for the last seven days that illustrates all of these concepts. The report queries for the metrics Sessions and Avg. Session Duration and the dimensions Browser and Operating System. It then filters the results to only include rows where the Operating System value is “Windows”:

Browser Operating System Sessions Avg. Session Duration
Chrome Windows 598,713 00:03:54
Firefox Windows 127,904 00:02:49
Internet Explorer Windows 23,864 00:02:39
Opera Windows 11,436 00:03:04
Edge Windows 10,208 00:03:00

As you can see, Chrome is the most popular browser for Windows users, and Chrome users spend more time on CodePen than people who use other browsers.

Getting Answers to CodePen-Specific Questions

The first two questions in our list are about differentiating between users: logged in users vs. anonymous users and PRO users vs. non-PRO users.

Since Google Analytics doesn’t know anything about PRO accounts or the CodePen login system, there’s no way it can track this information by default. We can give it this information though!

Tracking Custom Data

If Google Analytics doesn’t have a built-in field for tracking the information you want, you can create your own field. These are known as “custom dimensions and metrics“.

We’ve already mentioned that dimensions are a way to subdivide metrics into relevant categories. A user’s logged in status as well as whether or not they have a PRO account is ultimately just a subcategory of the metric users, so we created custom dimensions to track both of these.

Custom dimensions have to be created in your Google Analytics account settings, and once they’re created, you can send values for them in the hits you send to Google Analytics.

The easiest way to send custom dimension data with your hits is to set their values on the tracker object. Since all hits sent from a tracker include all the key/value data it’s currently storing, setting custom dimensions on the tracker will ensure those values get sent with all future hits.

Here’s the change we made to our tracking code to set the “Logged In” and “PRO” custom dimensions:

ga('create', 'UA-XXXXX-Y', 'auto');

ga('set', {
  dimension1: __isUserLoggedIn__,
  dimension2: __isUserPro__

ga('send', 'pageview');

The variables __isUserPro__ and __isUserLoggedIn__ are boolean values passed from Rails to the view templates (and ultimately turned into JavaScript variables), and the keys dimension1 and dimension2 correspond to the custom dimension index shown in our Google Analytics account settings.

Chris: this is big for us. Imagine for every single report you’ve ever seen in Google Analytics being able to be like “Now show me this same data, but only for PRO users.”

Now that we’re sending these two custom dimensions with all our hits, we can query for “PRO” or “Logged In” status in any of our reports.

An Example of a Custom Report with Custom Dimensions

Here’s a report that displays the Avg. Session Duration and Pages / Session metrics subdivided by the “PRO” and “Logged In” custom dimensions.

PRO Logged In Avg. Session Duration Pages / Session
Yes Yes 00:09:08 6.51
No Yes 00:07:50 6.12
No No 00:02:43 2.53

Now that we have this data at our fingertips, we can see PRO and logged in users spend quite a bit more time using CodePen than anonymous users.

Here’s an example of the same kind of data, only looking at Bounce Rates across multiple dimensions:

More Accurately Tracking Users Across Browsers and Devices

By default, Google Analytics identifies users by storing a random ID value in your browser’s cookies. This works to identify returning users on the same browser, but it doesn’t work well if a user visits CodePen on multiple different browsers or devices, and since people who use CodePen often use it for cross-browser or cross-device testing, this happens a lot.

If your site has its own way of identifying users (such as a login system) Google Analytics lets you send that as the User ID in addition to the Client ID that’s stored in the cookies. Google Analytics can then do a much better job of determining that two users are in fact the same person, and not counting them twice.

To use the User ID feature with Google Analytics, all you have to do is enable the setting in your account and then set the value on the tracker object:

ga('create', 'UA-XXXXX-Y', 'auto');

ga('set', {
  userId: __userID__,
  dimension1: __isUserLoggedIn__,
  dimension2: __isUserPro__

ga('send', 'pageview');

Measuring User Activity

The third question in our original list was to figure out how many of our total users have been active recently. Google Analytics has an Active Users report that gives you active-users metrics for the past 1, 7, 14 and 30 days.

For example, the 30-day Active Users metric is a count of the total number of unique users who’ve interacted with your site at least once in the last 30 days. At CodePen we can look at our database to see how many total user accounts have ever been created, but a much better metric for getting a sense of our “real” user base is to know how many of them have been active recently.

As the chart above shows, on February 19, 2.6 million different people had used CodePen at least once in the previous 30-day period. On January 1, that number was only 1.9 million. Some of that difference is probably due to lower holiday traffic, but in general it’s clear that the number of active CodePen users is increasing.

Tracking User Interactions with Events

The default tracking snippet captures page loads, but it doesn’t track anything the user does while on that page. To capture more relevant data we needed to send more relevant interaction hits. We did this using events.

Having the initial list of questions we wanted to answer made it really easy to decide what events to start tracking. Here are the two we’ll focus on in this section:

  • When users change the layout of the editor, which do they prefer: top, left, or right?
  • When users “heart” or “comment” on Pens, what view are they in?

Starting with the first one, the CodePen Editor consists of three panes (HTML, CSS, and JavaScript) that can be either on the top, left, or right of the window. This placement can be changed by clicking the “Change View” button in the top right of your screen and then choosing one of the options under “Editor Layout”.

Since we have JavaScript code that runs whenever someone clicks one of those options, we can send an event to Google Analytics and include the chosen Editor Layout setting.

Here’s the basic gist of how we did that in our code:

function handleEditorLayoutChange(placement) {

  // Do the change...

  // Then report it:
  ga('send', 'event', {
    eventCategory: 'Editor Layout',
    eventAction: 'change',
    eventLabel: placement


Now that we’ve started collecting these events, we can run a report for the metric Total Events and the dimension Event Label. We also have to filter the results to only include events with the Event Category dimensions set to “Editor Layout” and the Event Action dimensions set to “change”. Here’s what the results look like for the past 30 days:

Event Label Total Events
Left 73,186 (50.4%)
Right 37,204 (25.6%)
Top 34,794 (24.0%)

As you can see, the majority of the time people are changing the Editor Layout, it’s to display the code panes on the left.

To answer the second question, what view users “comment” or “heart” Pens from, we added logic to send an event whenever a user posts a comment or hearts a Pen.

The “view” a user is in can be found by inspecting the URL. For example a URL matching the pattern /<profiled-username>/pen/<pen-id> is “Editor View” and a URL matching the pattern /<profiled-username>/details/<pen-id> is “Details View”.

To figure out which view users typically leave comments from, we queried for the metric Total Events and the dimension Page (the URL path). We then filtered the results so the Event Category was “Comments” and the Event Action was “posted”. Lastly, we had to use a regular expression to get results for all URLs matching the “Pen View” pattern, and in a second query we used a different regular expression to get all URLs matching the details view pattern.

Based on CodePen data over the past 30 days, we can see that users add comments from the Pen View about three times as often as they add it from the Details View:

Page Total Events
/<profiled-username>/pen/<pen-id> 2940 (73.5%)
/<profiled-username>/details/<pen-id> 1058 (26.5%)
Chris: This was surprising to me at least. I thought Details View would be the go-to for commenting activity. Then again, the whole reason we created the “pop up” comments area in the Editor was to encourage commenting from there. So, win!

Drilling down into the data using segments

We’ve shown how you can use dimensions and filters to subdivide your metrics into categories. This is powerful, but in both cases your queries are still operating on your entire data set.

Another way to drill down into your data is to use segments.

Unlike report filters which exclude individual rows from a list of results after the query is run, segmentation filters out sessions or users before running the query. For example Google Analytics comes with some built-in segments such as “Organic Traffic” and “Made a Purchase”. However, just like with built-in reports, the most useful segments are going to be ones that are specific to your app’s data.

For example, in CodePen we might want to create a segment to only include (or exclude) any of the following:

  • Users who are coming to CodePen for the first time
  • Users who have hearted at least one Pen
  • PRO users using Professor Mode
  • Sessions where the user didn’t create a new Pen
  • Sessions where the user edited a pen on a tablet

Remember that Google Analytics uses a data model of users, sessions, and interactions. With segmentation you can remove entire sessions or users (and thus all the interactions that belong to them) for the data a query operates on. What makes this really powerful is you can apply a segment or any of the built-in reports or any of your custom reports.

To give a specific example of a report run on only a segment of the data, consider the following question: What are the most commonly visited pages by PRO users when they’re not creating new Pens?

Here’s a screenshot of how you might build that custom segment in Google Analytics:

And here are the results (filtering out pages of pens by a specific user).

Page Pageviews
/ 71565
/login 7789
/pens/ 6998
/picks/2/ 2145
/posts/ 2069
/patterns/ 1129

To ask another, slightly more complex segmentation question: Do PRO users heart more pens, percentage-wise, than non-PRO users?

To answer this question we have to create four segments and run four queries. For each of the segments in the table below we ran the query for the metric Sessions for the past 30 days (note, these queries didn’t have a dimension):

Segment Sessions
Sessions from PRO users 71337
Sessions from PRO users containing a “heart” event action 4945
Sessions from Logged-in, non-PRO users 832597
Sessions from logged-in, non-PRO containing a “heart” event action 36610

Then we do a little math and we get the percentages:

% of PRO user sessions containing a “heart” event action 6.93%
% of non-PRO user sessions containing a “heart” event action 4.39%

As you can see, it’s almost 60% more likely that a PRO user will heart a pen during a session than a non-PRO user.

Using a Plugin to Track Common User Interactions

The last question we had was about what links our users were clicking on that took them to other sites. The primary reason we wanted this data was to see what links people were clicking on our Job Board.

If you’ve ever installed Google Analytics on a site before, you’ve probably noticed it tracks link clicks to other pages on your site, but it doesn’t track links clicked to external sites. The reason is that Google Analytics uses first-party cookies to identify new and returning users, and first-party cookies can only be shared within the same domain.

If you want to track what external links users are clicking on, you have to track those clicks with events.

Instead of implementing outbound link tracking ourselves, we used the autotrack plugin to do this for us. Autotrack comes with a set of plugins for tracking common user interactions. Theres a bunch of things it can help with, but the main one we wanted was the outboundLinkTracker plugin.

To install autotrack we added the `autotrack.js` file to our main JavaScript bundle, and we added the following line to our tracking code. All together now:

ga('create', 'UA-XXXXX-Y', 'auto');

ga('require', 'outboundLinkTracker');

ga('set', {
  userId: __userId__,
  dimension1: __isUserLoggedIn__,
  dimension2: __isUserPro__

ga('send', 'pageview');

Once we had outbound link tracking set up, we could create a custom report for the metric Total Events and the dimension Event Label that filtered on the dimensions Event Category equals “Outbound Link” and Event Action equals “click”.

Here were the top five outbound link clicks. We’ve anonymized the job posting URLs for privacy reasons.

Link URL % Total Outbound Link Clicks
http://blog.codepen.io/ 24.29%
<job-posting-link> 11.38%
http://blog.codepen.io/store/ 9.44%
<job-posting-link> 7.13%
<job-posting-link> 5.98%
Chris: It’s nice to see so many outgoing clicks going toward jobs, as that’s a big growth area for us. Three out of the top five most-clicked outbound links were to jobs. We may explore tracking those clicks even more specifically so we can provide that data to the companies who post jobs.


Honestly, the most surprising and refreshing part about upgrading the Google Analytics game at CodePen was how little code needed to change. It was mostly:

  • Add some custom dimensions and update the trackers to send them
  • Sprinkle some event tracking in important places
  • Build custom reports to see the data

We added the custom dimensions for PRO and logged in users, the autotrack plugin, and then a few lines of event tracking code, and we dramatically increased the types of reports we could run.

Once we learned how to create custom reports and custom segments, we suddenly felt like we were the ones in control and the ones asking the questions. Previously we mostly just clicked around the built-in reports, hoping some insight would jump out at us, and it usually didn’t.

If you want to improve your site’s analytics, hopefully this article piqued your interests and helped you get a sense of what’s possible.

If you want to learn more, here are a few places you should start:

  • Analytics Academy courses: these courses are a series of short video lessons that explain many of the core concepts of Google Analytics. Course 1 and Course 2 are great for getting a high level overview of how the platform works, and should help you better answer the questions specific to your situation.
  • The analytics.js developer documentation: The guides in the “Fundamentals” section in the sidebar give a great overview of how the analytics.js library works and what can be done with it. Also check out the field reference for a comprehensive list of what fields and options can be set on tracker objects.
  • Dimensions and Metrics reference: when you make custom reports (or make API requests), you have to tell Google Analytics what dimensions and metrics to use, which is difficult if you don’t know what the options are. This tools lets you browse and search through all the choices.
  • Query Explorer: if you want to automate running your custom reports, you’ll need to make API requests. The Query Explorer is a tool that helps you build API requests. And actually, for quick, one-time custom reports, you can often do them faster in the Query Explorer than you can in Google Analytics.

If you need help, the help page on Google Analytics Developers has links to point you in the right direction.

More in the video!

Here’s us chatting about all this and showing off a ton more about CodePen and Google Analytics: