Capture Content Metadata Using Custom Dimensions and GTM

Tracking content performance frequently involves spreadsheets with countless Vlookups matching content URLs to metadata. Or tricky URL parsing functions that extrapolate information, like category or date. If you use Google Tag Manager (GTM) on your site, it doesn’t have to be this way. With a few tweaks you can have your very own front-end solution for tracking content metadata.

If you’re not running GTM yet we’ve got a great introductory post from Tim Allen. I’d recommend you start there. In this post I’ll assume you’re up and running with GTM and have at least a passing familiarity with JavaScript.

Now, let’s explore how to use this tool to capture metadata about your posts for use in Analytics reports. Our goal will be to take a blog post “category” value from a page and put it into a custom dimension in Google Analytics.

There are four steps to this process:

  1. Configure Google Analytics

  2. Configure a Google Tag Manager macro to capture category information

  3. Configure the GTM pageview tag to use our macro

  4. Publish GTM changes

Configure Google Analytics

In order to record data in Google Analytics (GA) we’ll be setting up Custom Dimensions. Basically, we need to give GA a heads up that this category data is coming. Custom Dimensions are first-class citizens in GA—once defined, they show up in all reports where they are relevant, just like any other dimension. The one caveat is that they can’t show historical data. Only data you record going forward will show up.

The configuration panel for Custom Dimensions is in the ‘Property’ section of the admin panel.

...which leads to:

From here we’ll create a new custom dimension:

Not much to it—name the category appropriately, make sure the scope is set to ‘Hit’, that it’s active, and click 'create'. Setting the scope to ‘Hit’ indicates that our Custom Dimension records information about an individual pageview, as opposed to, say, an entire session or user.

Now that GA is ready to receive, we need to capture category information in GTM.

Configure a Macro

In order to send the category data to GA, we’ll need to capture that information using GTM and include it in the pageview sent whenever a user visits a blog post.

...which will lead you to:

This is the secret sauce that makes the whole thing work. We’ll use the ‘Custom JavaScript’ macro type to execute a JavaScript function. This function will capture information from an on-page element.

In this case, our example function looks for an element on the page with an id of 'category'. The text, for your reference, is below. I’ve added some comments to explain it:

function() {
    /* Define a regular expression to match only blog posts. */
    var blog_pattern = /example\.com\/blog\/.+/i;
    var content_type = null;

    /* We will only try to assign categories to blog posts. All
       other pages will have (not set) as their category. */
    if (blog_pattern.exec(document.URL) !== null) {
        content_type = document.getElementById("category").textContent;
    } else {
        content_type = "(not set)";

    return content_type;

Now, whenever we reference {{blog category}} in GTM, this function will run. Whatever value for content_type is returned will be used to set a value for this macro.

This is where you will need to exercise a bit of JavaScript ingenuity to capture the information you want. Every case will differ. I’ll offer one more example to get you going. Imagine instead of categories, we want to capture tags. Normally a blog post can have one category, but many tags. We’ll capture them in a field by separating them with pipes—imagine “Web Analytics | SEO”. A function to accomplish this:

function() {

    var blog_pattern = /example\.com\/blog\/.+/i;
    var content_tags = null;

    if (blog_pattern.exec(document.URL) !== null) {
        /* Assumes tag elements have a class “tags”. A relevant identifier
           will be different in your case. */
        tags = document.getElementsByClassName("tags");
        content_tags = tags[0].textContent;

        /* If there is more than one tag, add pipe and add’tl tag. */
        if (tags.length > 1) {
            for (i = 1; i < tags.length; i++) {
                content_tags = content_tags + " | ";
                content_tags = content_tags + tags[i].textContent;
    } else {
        content_tags = "(not set)";

    return content_tags;

Again, just an illustration as an example of what might be done. You may have to concoct something completely original—or ask one of your web developer buddies for help!

Configure Your Pageview

Now that we have access to the category information via our “category” macro, we can use that macro to append a page’s category information to its pageview.

Let’s check out our pageview tag—the type that is commonly fired on every page of a site. In the ‘More settings’ section at the bottom, add a listing to the ‘Custom dimensions’. Specify the number of the custom dimension created back when GA was configured to accept this custom dimension.

In the “dimension” field, specify the macro that captured the blog category. A valid setup would look something like this:

Save your changes and then…


Once everything is set, we can hit ‘Publish’ in GTM. The collected data will show up as a first-class dimension in Analytics with whatever title we specified for the Custom Dimension. Look to use it in content reports, custom dashboards, or even with the Google Sheets GA add-on.

Once you have this pattern down, it is easy to replicate for other types of data that appears on your published content. Anything from post date to tags to author can be captured and included in Analytics reports.

What data would you track for your content? Let us know in the comments, and look out for more content-centric blog posts this month!

Get blog posts via email

About the author
Benjamin Estes

Benjamin Estes

Ben is a Principal Consultant who joined Distilled in 2010. Now he focuses on leveling up our team. Through group training and internal consultation, he guides team members as they effect change for our clients.   read more