If you're interested in tracking the ROI of adding semantic markup to your website, while simultaneously improving your web analytics, this post is for you! Join me, friend.
Semantic markup and structured data: Can I get a heck yes?!
If you haven't heard of semantic markup and the SEO implications of applying said markup, you may have been living in a dark cave with no WiFi for the past few years. Or perhaps you're new to this whole search marketing thing. In the later case, I won't fault you, but you should really check this stuff out, because it's the future.
That said, I'd wager most people reading this post are well acquainted with semantic markup and the idea of structured data. More than likely, you have some of this markup on your site already and you probably have some really awesome rich snippets showing up in search.
Organic snippets like these are why most SEOs are implementing semantic markup. I don't think we need to debate that. Everyone wants to get those beautiful, attractive, CTR-boosting rich snippets and, in some cases, you're at a competitive disadvantage simply by not having them.
If you're like me, you love seeing your sites earn rich snippets in Google's search results. I loved it so much that I let myself believe that this was the end goal of semantic markup: landing the rich snippet. When I implemented markup for various entities on the sites I worked on, I'd get the markup added to the site's code, verify that it was successfully crawled, watch the rich snippet show up, and then call it a victory! Hooray!
Tracking the ROI of semantic markup
Well, I've come to the realization that this simply can't be the measure of success for your semantic SEO strategy! What difference does that rich snippet really make? C'mon, be honest. Do you know what the real impact was? Can you speak to your boss or your client about how pages with a specific type of markup are performing compared to their non-marked up counterparts? Another question to ask: Are you leveraging that semantic data for as much value as you can?
Is there a way to more effectively track the ROI of semantic markup implementation while simultaneously giving us a deeper level of insight regarding how our site is performing?
The answer is yes! How? It's (relatively) easy, because we've already done the hard work. Through applying semantic markup to our site, we've embedded an incredibly rich layer of meaningful data in our code. Too often, SEOs like us forget that the idea of the semantic web extends far beyond search engines. It's easy to add schema.org entity markup to our pages and and think that it ends when search engines pick up on it. But that can't be the end of the story! Don't let the search engines have all the fun; we can use that data, too.
By looking at the semantic markup on any given page, we can see what type of "entity" we're looking at (be it an "Event," "Person," "Product," "Article," or anything else) and we can also see what attributes or properties that entity has. If we could gather that information and pump it into an analytics platform, we'd really have something great. So let's do that!
Using Google Tag Manager to record structured data
Google Tag Manager was the game changer I didn't know I needed. There are a few great posts that provide nice overviews of GTM, so I won't get too deep into that here, but the key capability of Google Tag Manager that is going to allow us to do amazing things is its inherent ability to be awesome.
Okay, let me explain.
The value of any tag management platform lies in its ability to fire off tags dynamically based off of Rules and Macros. This is incredible for anyone doing advanced analytics tracking because you can attach granular tracking elements to various sections of your site without (theoretically) ever having to touch your code. Need to track a click on an image banner in your sidebar? Just set up a Tag in Google Tag Manager that fires based on a Rule that uses a Macro to identify that image banner in the code of your site!
So what I'm ultimately trying to share with you through this post is a methodology for using GTM to bring your semantic markup in to your analytics platform so you can not just track the ROI of adding semantic markup to your site, but leverage that markup for a deeper level of insight into your data. I've taken to calling this "semantic analytics."
Tags, rules, and macros
Before we get into the nuts and bolts of how this all works, let's go over Tags, Rules, and Macros in Google Tag Manager.
- Tags: In the context of analytics, a Tag is any piece of tracking code that is going to send information back to Google Analytics (or your analytics platform of choice). Nearly every site on the web is going to have a basic pageview tracking Tag on every page; every time you load a page, that Tag is fired and sends information about that pageview to an analytics platform (e.g. Google Analytics). But we can get even better intelligence by having additional tags send other information into Google, like "event" tags which can send information for things that happen on the site (clicks, scrolling, non-click interactions, video plays, etc.). Google Tag Manager lets you configure any Tag you want, which will fire based on a Rule.
- Rules: A Rule in Google Tag Manager tells a Tag when to fire. Without a Rule attached to a Tag, it will never fire (i.e. send info to Google Analytics) so the most basic Rule is one that is triggered on every page. However, you could set up a thank-you page conversion event tag for AdWords, for example, that only fires on a page with a URL matching /contact-form/thank-you/.
- Macros: Macros are by far the most powerful features in Google Tag Manager. Their power seems almost limitless, but the key thing we'll be looking at here is the ability to create a JavaScript Macro that will look in the DOM (Document Object Model) for specific elements. This allows you to look for specific elements in the HTML and fire events based on what you find.
What we'll want to do in Google Tag Manger is create a Macro that looks for semantic markup in the code of a page. We can then use a Rule to fire a Tag every time someone views a page that has semantic markup on it and include event labels that record what type of entity that person looked at. Ultimately, this will let us drill down into analytics and view reports to see how marked up pages perform against their non-marked up counterparts. We can even pull out granular properties of entities and analyze based on those (for example, pull the "performer" item property out of all "Event" entities and see which "performers" got more traffic and/or led to more conversion events).
Setting up semantic analytics
So let's walk though the whole semantic analytics process using a website that lists industry events as an example. Since I'm familiar with it, let's use SwellPath.com as our example since we list all the events we present at in our Resources section.
For each industry event on our site, we have semantic markup that specifies the Event schema.org itemtype and defines various associated itemprops, including the speaker (itemprop="performer"), venue (itemprop="eventVenue"), event name (itemprop="name"), and time (itemprop="startTime"). At the most basic level, I want to be able to track all the pages that have Event markup. If I wanted to get ambitious (which I do!), I want to pull the speaker name, event name, and venue name, too.
To do this, we'll want to set up a Macro, which is the condition for a Rule, which then fires a Tag. However, we're going to dive into that progression in reverse order. Yeah, we're going full Tarantino.
Setting up the Tag
The Tag we want to set up in Google Tag Manager will look like this:
The category for all of our semantic events will be "Semantic Markup," so we can use it to group together any page with markup on it. The event action will be "Semantic - Event Markup On-Page" (even though it's not much of an "action," per se). Finally, we'll want to make the label pretty specific the individual item we're talking about, so we'll pull in the speaker's name and combine it with the even name so we have plenty of context. We'll use a Macro for that, but more on that below.
Configuring the Rule
Without a Rule though, our Tag won't ever fire. We can't just set it up to fire on every page, though; we need to have a Rule that says "only fire this tag if semantic markup is on the page." Our Rule will include two conditions.
- The first condition looks for an event that is equal to "gtm.dom". This is an event that Google Tag Manager can pick up out-of-the-box and it means the that Document Object Model (DOM) finished loading (in simple terms, the page finished downloading). The reason we need this is because we need to tell Google Tag Manager to look in our code to find semantic markup; it doesn't make sense to do that before the page has finished loading.
- The second condition for our Rule is a Macro that's going to look for specific markup on the page.
Building the Macro
The Macro is the really cool part! To get it set up, we'll create a Macro that uses "Custom JavaScript." Inside of the Macro, we essentially want to create a function that looks for our itemtype tag from schema.org on the page and returns either "true" or "false". The screenshot that follows shows what it looks like when you set it up in Google Tag Manager, but I've provided the text of the Macro as well so you can cut and paste.
function () { var SemElem = document.querySelectorAll('[itemtype*="Event"]'); SemElem = SemElem.length > 0 ? true : false; return SemElem; }
Keep in mind that I'm using jQuery here to make sure it works across most browsers. Make sure that whatever site you implement this on also has jQuery installed, or this Macro won't work.
While we're here, we'll also create a Macro to pull out specific itemprops that we want to use later. Specifically, the event name and the performer name. We can then combine those two variables in our Macro function to form a sentence that we'll use as an event label later on. I also added an If statement so that it returns "No semantic data" if any important events are missing.
function () { var venue = $('[itemtype*="Event"] [itemprop*="name"]') [0]; var performer = $('[itemtype*="Event"] [itemprop*="performer"]') .text(); venue = $(venue).text(); label = performer + " at " + venue + " (Semantic Event)"; check = venue.length > 0 ? true : false; if (check === false) { label = "No semantic data"; return label; } else { return label; } }
Putting it all together
To actually set this up in Google Tag Manager, you'll set up all the elements we just discussed in reverse order (do you get my previous Tarantino joke now?). First, create your Macros in GTM. Then create your Rule using the Macro you just created as one of the criterium. Finally, create your Tag that fires based on the Rule.
From there, you can push the new version of your GTM Container Tag live. If you're smart, though, you'll run it in Debug Mode first and make sure that you have it set up correctly.
Naming Conventions
What good is a standardized vocabulary for your web data if you don't have a standardized naming convention for your Google Tag Manager and Google Analtyics set up? Here's what I use, but feel free to use what works for you:
- Macros: Semantic - {Item Type} Markup Detection
- Macros: Semantic - {Item Type} Markup Properties
- Rule: Semantic - Has {Item Type} Markup Rule
- Tag: Semantic - {Item Type} Markup Analytics Event
Making it even easier
Thanks to Google Tag Manager's amazing new API and Import/Export feature, you can speed up this whole process by importing a GTM Container Tag to your existing account. That way, you don't have to set up any of the above; you can just import it.
Editor's note: The download below is no longer available.
All you have to do is download this JSON file called " Semantic Analytics Headstart" (DropBox link) and then use the Import option in your Google Tag Manager account.
Within GTM, just select the Semantic Analytics Headstart JSON file you saved as your file to import, select Merge, and choose Overwrite. The only thing that this Container Tag has in it is the Semantic Macros, Rules, and Tags, so Merge and Overwrite will simply add these special features to your existing configuration. Just note that the Semantic Tags reference a Macro that contains your Universal Analytics tracking ID (i.e., make sure to edit the Macro called "Universal Anatlyics UA-ID" and put in your own tracking).
Semantic data in Google Analytics
Congratulations! You now have all the pieces in place to start receiving semantic data in Google Analytics. Go ahead, go check your Real Time Events report. I'll hang here.
Okay, seriously, how cool was that?
There's something incredibly special about giving your data meaning. Whether you get that by having an intimate relationship with your data platform, having super-advanced tagging in place, or making your analytics truly semantic by applying the principles of the semantic web to your data collection, you're doing something amazing. Now that you have semantic data in your analytics, you can drill down into specific categories and get some really cool information.
Another path
I feel like passing in semantic data as Events in Google Analytics is fairly straightforward, and the step-by-step process makes it fairly easy to grasp, but there's another (perhaps even better) way to add semantic data to your analytics. In analytics speak, a "dimension" is a descriptive attribute of a data object. Sounds pretty similar to itemprops on the semantic web, eh? So, why not set up Custom Dimensions in Google Analytics and use those to enhance our semantic analytics? Let's do it!
Fortunately, we've already put a lot of the pieces in place to access our semantic data, so we just have to create the Custom Dimension in Google Analytics and shoot data to it by adding a field in GTM. First, go to the Admin panel in you Google Analytics account and go to "Custom Definitions" > "Custom Dimensions". From there you'll want to create a new Custom Dimension called "Semantic Markup" with the "Scope" of "Hit" and set it to be active.
Make a mental note of what the index is; you'll need to specify it in Google Tag Manager. With the Semantic Event tag that we set up in GTM, we created an entirely new tag that would fire something on pages with semantic markup. For Custom Dimensions, we'll want to add something to our general analytics.js tag (the basic pageview tracking for Google Analytics). Once you find your main analytics tracking code in the list of tags, open it up and scross down to Custom Dimensions (under More Settings). Click the button to "Add Custom Dimension" and use the same index that you made a note of and, for the Dimension field, we'll use the same Macro we used for our Event label: Semantic - Event Markup Propertites.
Once you have this set up, you'll be able to bring in a "Semantic Markup" dimension to almost any Google Analytics report. Here's an example All Pages report that now displays Semantic Markup in addition to the Page URL.
I introduced this Custom Dimension approach as "another path," but really, I like to use it as a supplement and work both angles. Having both semantic events and semantic dimensions set up in Google Tag Manager won't cause any issues; it will just give you more meaningful data. Who doesn't love that?
Looking forward with semantic analytics
What can you accomplish by a applying semantic values to your data? That's what I'm most excited to find out.
I'm working on getting this up and running on sites that publish tons of content (Article markup), process thousands of eCommerce transactions (Product markup), and have lists of experts (Person markup). I'd love to see what semantic analytics could do for local business directories (Yelp), movie sites (IMDB), car dealerships, and recipe sites (my buddy Sam Edwards is already looking to implement this idea for Duncan Hines).
One of the biggest "mind blown moments" of my career was when I discovered that there was a whole semantic web community out there that wasn't just concerned with marking up content to get better looking snippets in the SERPs; they wanted to use semantic markup to make data more accessible and meaningful and to make the web a better place to be. I'm hoping that amazing folks like Aaron Bradley and Jarno van Driel will be able to help evolve this concept and inspire widespread adoption of semantic analytics.
If you have any questions, ideas for how this could be applied, or ways to extend this concept, let me know in the comments! Happy optimizing.
Mike,
This post rocks! Thanks for being honest at the beginning, mentioning that in the past you just stopped at seeing the rich snippet in SERPs… and moved on. I've definitely done the same, and I'm sure most others have, as well.
Wow, I'm crazy about the custom dimension aspect of this! Just the idea of being able to sort by landing page and see what pages have semantic data implemented and which ones don't? I'm not entirely sure how I'd use that right now, but surely that's a really big deal and incredibly useful. Awesome.
I do have a question though, so please bare with me. :)
Was wondering why simply - since semantic markup is on the page-level - analyzing the page(s) before and after the rich snippet was populated is not enough?
Obviously all the tag manager and custom dimension work provide significantly more possibilities, but couldn't we make good observations and correct correlations just from landing page data (sessions, uniques, CTR, impressions, etc.)? Looking forward to hearing your answer!
Great post, man.
The problem I was having was with clients who didn't have a logical URL structure. We implemented product semantic markup on product pages and the client later want to know how products with semantic markup from "manufacturer X" performed versus products that didn't have markup on them. Because of the funky URL structure, there was no way to build a page group or filter in Google Analytics and answer that client's question. Now with this, we can just pull in pages with semantic data and filter for that one manufacturer the client cares about.
If you have a meaningful URL structure, you can certainly get some high level performance data just by using that. But implementing semantic analytics will let you delve infinitely deeper.
Thanks for reading and for asking a great question!
Ahhhhh, yes. Those complicated e-commerce websites/pages without logical URL structures! Great stuff, Mike. I look forward to getting a chance to implement this in a client campaign.
Amazing stuff Mike - so much for putting this together and making the headstart file available to all!
Correct me if I'm wrong, but with the right technical chops one should be able massage this framework in order to:
Extract semantic data from vocabularies other than schema.orgExtract semantic data that's encoded in other syntaxes besides microdata, such as RDFa and - especially - JSON-LDRight? :) I say "especially JSON-LD" because that opens up the exciting possibility of making very good use of data that may be easier to encode (and may be more reliably encoded) than by including it in inline markup, regardless of the current ability (or will) of the search engines to make use of JSON-LD-encoded structured data.
Always so flattering to get feedback from you, sir! You are NOT wrong! You can absolutely tweak this to grab any kind of semantic markup on a given page. I'd go so far as to say that as long as it lives in the DOM, you're golden.
For example, you could use this jQuery in a GTM Macro and grab the "type" attribute from JSON-LD in your <head> and return it as a variable you can use in Google Analytics.
function() {
var semanticJSON = $("head script[type='application/ld+json']").text();
var semanticType = JSON.parse(semanticJSON)["@type"];
return semanticType;
}
Adapt and tweak as needed. I've been working with this for what feels like a few months not stop and I'm still buzzing about it!
As usual you've gone above and beyond - thanks Mike, great stuff!
Sweet! Could have done with this post six months ago.
I know, right? ;-)
Great article. Do you have any advice/insight on how to track markup that perhaps doesn't always display? I have a client for whom the schema star rating is very important. Even though the markup is implemented correctly, according to Google's structured data testing tool, it doesn't always show, in fact we haven't seen it once!
I know Google does pick and choose when to display star ratings, but it would be great if there was some way for us to know if it had actually shown to a user in a SERP using GTM and then we can track its influence too (if it ever starts showing that is!)
Thanks again, I look forward to hearing your thoughts.
James
Thanks, James! That's a tricky one, but it's actually the headscratcher that led me to develop this. I wanted to see how many people were clicking through on organic results when structured data was displayed. However, there's nothing in the referring data from a Google SERP that communicates whether or not the result someone clicked on was showing an actual snippet or not. The best I could do was track the semantic markup on-site and go from there.
So for right now, I don't believe there's a way to do that using GTM. You could, however, develop a program to scrape Google SERPs on a daily basis and have that send an Event to Google Analytics through their API if a rich snippet was showing up on that given day.* Then you could analyze how traffic performed when rich snippets were showing up.
Thanks again for reading!
* Entirely theoretical and untested.
Hello Mike, thanks for your speedy reply. I'm a novice when it comes to using GTM so I'm gonna dive into some articles and bend some ears to see if its possible. I'll let you know if I manage to crack it!
Thanks again.
Great article. Do you have any advice/insight on how to track markup that perhaps doesn't always display? I have a client for whom the schema star rating is very important. Even though the markup is implemented correctly, according to Google's structured data testing tool, it doesn't always show, in fact we haven't seen it once!
Thank you for share this article about sementic analytics, because it is very important to analice a web page business and its ROI.
Hi Mike, I also have heard a lot about structured markup and want to implement. However, I have an active site hosted on blogger.com. Do you know of any good tools which can help add structured markup easily for blogger posts? Thanks for the help in advance.
Hey Mike,
What a great post! It's indeed one of the best post on Semantic markups, I'll surely gonna try it out soon.
I just have one question, what is limitation of this method? If I'm getting the reviews and ratings from third party, will this method still gonna work?
Umar
Thanks for reading (and submitting to Inbound.org!). That's a great question. The great thing about Google Tag Manager is that all it cares about is the code that loads onto the page; it doesn't matter where it comes from. The only tricky thing is that you'll have to adjust the JavaScript Macros to look for the code signatures in the third party plugin. Shouldn't be too challenging though, especially if you are technically inclined (or know someone who is).
Thanks Mike. I'll surely gonna try it out and back to you if I need anything :)
An amazing post !! As I searched on the semantics and little information so concrete and practiced there in the online world .
Please enlighten us Mike !
Semantic analysis is not one of my strong points but thanks to your article I understand the basics. In addition, I am entitled to a full course on using Google Tag Manager. Thanks!
Thanks for this! Really helpful.
Very good information to know which is the semantic web and applications have when creating our own website.
Highly recommended to keep this information in order to have an great position in the web.
To this day still one of my favorite blog posts I've read on the internet!
Sweet!!! Could have done with this post six months ago.
Thanks for reading (and submitting to Inbound.org!). That's a great question. The great thing about Google Tag Manager is that all it cares about is the code that loads onto the page; it doesn't matter where it comes from. The only tricky thing is that you'll have to adjust the JavaScript Macros to look for the code signatures in the third party plugin. Shouldn't be too challenging though, especially if you are technically inclined (or know someone who is).
Great post, Mike.
Thinking about the new custom dimension included ("No Semantic Data"), it could be a good idea to have a dimension which labels the type of semantic markup included and not just whether it exists or not.
For example. a content site can compare articles with and without videos against each other, articles with and without images (and how many), length of articles, and a host of other properties that can be used to tag content up. From this perspective, you can see the page elements which return favorable metrics and adjust your content strategy.
To my favorites!! is very important to me to know this class of technics
Thank you very much for sharing, it´s very interesting :-)
Thanks for the info, much appreciated!
quick question: Does the "Tracking ID" have to be the actual tracking ID or is {{Universal Analytics UA-ID}} the actual tag? Does it call from the Analytics tag that should already be implemented into GTM?
Amazing post! Really complete! Thank u!
Thank you very much!
Thanks for the great info. Much appreciated help.
You're welcome. Thanks for reading. ;-)
Excellent post. I have been trailing using semantic markup in Analytics for some time now. It have given us some great great insight into exactly how users reach our site. I would definitely recommend that you take the time to set this up.
Excited that you're going to give it a go. Good luck and thanks for reading my post!
Wow really good post!
Thanks for the sharing
Thank YOU for reading! Cheers!
Such a wonderful post Mike; Just going to implement this semantic analytics and now it's time to see how my markup's are performing. :)
Thank you so much for explaining every step in detail.
Fantastic! Really stoked you found the information valuable.
Mike,
1.) Thanks for the hard work that went into developing this post!
2.) As a non-technical person, can this same approach be used with the "product" schema to enable improved analytics based on the inclusion of GTINs (UPCs) in product pages?
Hi Mike, thank you for this amazing post,you did a fantastic work in this post,how to use semantic analysis and structure data as a weapon to maximize the information.
Good timing for me to see this article! I am just about to make the case for schema markup and being able to say that we can measure the performance will help. Thanks Mike!
That's a hell of a post Mike! Kudos for putting that together :)
I do wonder though, just how grateful raghava0501 is for this. I have a sneaky feeling, not all that much ;)
On a serious note, schema does get confusing for many, let alone tracking it - definitely a post to refer people to!
-Andy
This is really awesome. I especially love the JSON import. Was not aware that you could do that in tag manager. This is going to make setting up custom analytics installs waaaaayyy easier.
Big hearts to you!!! <3 <3 <3