How to implement semantic markup using Google Tag Manager


Structured data is, at this point, a core SEO tactic.

Not only does it remove a layer of ambiguity for search engines (they don’t have to infer what a piece of data is; you’re telling them outright), it’s also the engine that drives rich results, which are taking up an increasing amount of real estate in the SERPs.

The advent of voice-enabled search is making structured data an even more important part of the search marketer’s toolset. In much the same way that structured data enables search engines to extract and reproduce rich data in the SERP, that same entity extraction and reproduction is at the core of voice search results.

Unfortunately, implementing structured data via semantic markup can be time-consuming and frustrating. Until relatively recently, the only way to implement semantic markup was to do so inline, by adding HTML attributes from to the existing HTML of a page.

To do so at scale, this historically required making changes to page themes or templates, which could be a big development ask depending on the site’s setup.

Plus, inline markup is by its very nature bound to the presentation layer: you couldn’t mark up pieces of data that weren’t on the page (with the exception of judicious meta tag use), and if two pieces of information weren’t close together on the page, it could be difficult, if not impossible, to link them together within a single itemScope tag.

Happily, the days of struggling to wrangle our data into easily-marked-up forms are behind us: it is now possible to add structured data in mere minutes using JSON-LD. This markup is now fully supported by Google and Bing; in fact, Google recommends adding structured data via JSON-LD instead of inline for Merchant Center accounts.

In the interest of clear and effective illustration, we’ll be using a fairly simple use-case in this first “Static JSON-LD section”. We’ll get more advanced once we arrive at “Dynamic JSON-LD”.

Know that even the more advanced example is just the tip of the iceberg; almost nothing is off limits when it comes to the level of complexity that Google Tag Manager-injected structured data can support.

Static JSON-LD

Static JSON-LD can be added to the <head> of the relevant page, or inserted using a plugin, but the easiest (and most flexible) way to implement it, in my opinion, is through Google Tag Manager (GTM).

Step one: Write the JSON-LD

If you’re unfamiliar with JSON-LD, you may want to do some reading or take a quick tutorial to familiarize yourself with the basic concepts. Google’s Introduction to Structured Data is a good place to start. Depending on the schema type you’re using, may also have examples of JSON-LD markup for that item type.

Example JSON-LD for the Event item type on

After the initial script tag, which tells the browser “this is a JSON-LD script”, you can see the hierarchy of our script:

  • “@context” specifies what semantic vocabulary (this of it as a shared dictionary for machines) we’re linking our data to – in this case, to the vocabulary.
  • “@type” is the specific schema, or entity type, within that we’re referencing. It’s the equivalent of “itemtype” in inline markup.
  • From there, we can directly reference specific properties within the schema by name. This is the equivalent of “itemprop” in inline markup.

Note that when we’re referencing sub-types such as Place, we need to call that @type separately, and put that sub-type in its own set of brackets to indicate which nested properties belong to said sub-type.

Don’t forget to put a comma after each property except the last one before an end bracket, or your code won’t parse properly (and it’s annoying to hunt through your code to find the missing comma)!

Once you have your code written, test it in Google’s Structured Data Testing Tool to make sure everything looks good and you don’t have any missing required properties.

Step two: Create a trigger

In Google Tag Manager, we want to create a trigger so that our JSON-LD markup tag will fire on the page we want it to fire on – in the example above, it would be on the page for the Typhoon with Radiation City event.

Create the trigger:

  • Type: Page View
  • Fire on: Some page views
  • Fire this trigger when: Page path equals the URL of your target page

Here’s what the trigger setup should look like

Step three: Create the tag

Now it’s time to create the tag that will fire on our target page and inject our JSON-LD structured data.

Create the tag:

  • Type: Custom HTML
  • HTML: Paste in the JSON-LD code, making sure to include the opening and closing script tags.
  • Triggering: Use the trigger from step 2.

Here’s what the tag setup should look like

Step four: Publish and test

Once you’ve published the tag, put the page URL back through the Structured Data Testing Tool to verify that Google can parse and understand it.

Voila, you’re done!

Dynamic JSON-LD

If you’re not adding new pages to your site every day, and the pages that are there don’t change that often, structured data via static JSON-LD may be all you need.

For sites like e-commerce sites, which may have thousands of products whose price and availability may be subject to change, however, static JSON-LD just isn’t scalable. We need to get a little bit fancy.

Step one: Create variables by CSS selector

Since we want this script to be dynamic, we’ll need to make use of GTM variables to find the pieces of data we need and give them names our script can understand.

Create a new (user-defined) variable. In this example, we’re creating a variable to grab the product name:

  • Give the variable a distinctive name, like “dataPoint – Product Name”; you’ll refer back to it later by this name.
  • Type: DOM Element
  • Selection Method: CSS Selector
  • Element Selector: The unique CSS selector for the element. In this example, the element’s class is product-name, so the selector is .product-name.

Repeat this step for each property you need to pull in to make your structured data validate.

Step two: Pull together in a function expression

Unfortunately, we can’t just pop our variables into our JSON-LD code and call it a day. Google Tag Manager inserts JavaScript to return its variables, and that JavaScript will invalidate our code.

Instead, we need to wrap our JSON-LD IN a function expression that will pull out our variables first, then merge theminto a JavaScript object, and finally insert a completed JSON-LD script tag into the head of the page.

The finished script in the Custom HTML tag (in GTM) should look something like this:

It may take a bit of tweaking and fiddling to get this to pull out your data exactly the way you want it; fortunately GTM’s Preview functionality will let you test as much as you need to before you deploy.

JSON-LD markup and AMP

Unfortunately, you can’t use GTM to inject JSON-LD structured data into AMP pages. GTM containers for AMP, like most things for AMP, are stripped-down versions of themselves. They don’t support the Custom HTML tag, or custom JavaScript variables, because they can take too long to load.

If your site is using  AMP, you may want to consider inline markup after all.

Once you get this methodology under your belt, you’ll find that implementing structured data has gone from a time-consuming slog of adding inline markup and bothering your developers, to something you can create and deploy in minutes.

Best of all, markup with JSON-LD fully validates, earns rich snippets, and is now supported by Bing as well as Google – so if you think it will work for your site, there’s no reason not to try it.

Related reading


Source link