Google has a myriad of ways to make the search engine results page (SERP) livelier. When you input a search query, the engine’s mission is to provide you with the most relevant information with as few clicks as possible. Often, this means that you’ll see the answer to your query directly in the SERP:

See also Dr. Pete’s excellent description of variation in the SERP (note that this post is from 2013, and not all the data types are relevant today). As you can see, there are many ways for a site to annotate data found within, and that way provide it for Google to utilize if it so chooses. There’s no guarantee that your structured data is picked up by the search engine, but that shouldn’t deter you from marking up your content anyway.

Now, to business. Google recently released a structured data testing tool that accepts JSON-LD as its input. JSON-LD is an offshoot of the JavaScript Object Notation (JSON) data format, mainly in that you can specify linked data nodes between different notation objects.

The structured data supported by JSON-LD is still quite limited, but the amount of options will surely amp up in the near future. Currently, you can markup your site content for:

  • All Knowledge Graph features

  • Event Rich Snippets

  • Sitelink search boxes

(UPDATE 3 Feb 2016) Support for Reviews and Products! Thanks Claudia Kosny for the tip.

The cool thing about this new release is the following quote from the support pages:

[JSON-LD] lets you embed a block of JSON data inside a script tag anywhere in the HTML...Also, Google can read JSON-LD data even when it is dynamically injected into the page's contents, such as by Javascript code or embedded "widgets".

Read the last part again. Doesn’t that sound like a Custom HTML Tag in Google Tag Manager? You bet it does!

Markup structured data using Google Tag Manager

You can dynamically inject JSON-LD specifications on your pages using Google Tag Manager. The only stipulation is that the code must be run during the initial page load. This means that you can’t dynamically enhance the structured data on the site after the window has loaded, that is, after gtm.load has been pushed into dataLayer. So as long as your structured data tags are executing with the All Pages Trigger, for example, you should be fine.

Here are some examples of Custom HTML Tags for structured data. Make sure the Tags fire with the All Pages Trigger.

Annotate social profiles for Knowledge Graph

If your site is included in the Knowledge Graph, it might be a good idea to add your social profiles directly to the SERP, as Marimekko have done:

Here’s what you need to write into the Custom HTML Tag:

<script type="application/ld+json">
{ 
  "@context" : "http://schema.org",
  "@type" : "Person",
  "url" : "https://www.simoahava.com/",
  "name" : "Simo Ahava",
  "sameAs" : [ "http://fi.linkedin.com/in/simoahava",
      "http://plus.google.com/+SimoAhava",
      "http://www.twitter.com/SimoAhava" ] 
}
</script>

The code above would annotate my Knowledge Graph box (if I ever reach such levels of stardom) with my social profiles directly in the SERP.

This, I think, is one of the coolest additions to the SERP. On some sites, you can see a search box directly in the sitelinks. This search box is tied together with the internal search engine of the site, allowing you to directly search for content within the site!

To get this to appear, the syntax of the code in the Custom HTML Tag needs to look like this:

<script type="application/ld+json">
{ 
  "@context": "http://schema.org", 
  "@type": "WebSite", 
  "url": "https://www.simoahava.com/", 
  "potentialAction": { 
    "@type": "SearchAction", 
    "target": "https://www.simoahava.com/?s={search_term}", 
    "query-input": "required name=search_term" } 
}
</script>

Here, I provide the URL and the necessary search query parameter that operate the internal site search engine on my site. Now, if someone were to enter a search term directly in the SERP sitelinks, they will be transported to the search results page within my site for that particular query.

Things to note

Remember that you can combine your various types of structured data into a Custom HTML Tag, and you should do so to reduce the number of tags in your container. The two examples from above would be combined into a single structured data push like this:

<script type="application/ld+json">
[{ 
  "@context" : "http://schema.org",
  "@type" : "Person",
  "url" : "https://www.simoahava.com/",
  "name" : "Simo Ahava",
  "sameAs" : [ "http://fi.linkedin.com/in/simoahava",
      "http://plus.google.com/+SimoAhava",
      "http://www.twitter.com/SimoAhava" ] 
},
{ 
  "@context": "http://schema.org", 
  "@type": "WebSite", 
  "url": "https://www.simoahava.com/", 
  "potentialAction": { 
    "@type": "SearchAction", 
    "target": "https://www.simoahava.com/?s={search_term}", 
    "query-input": "required name=search_term" } 
}]
</script>

Here I’ve included the two JSON objects, and inserted them into a single Array (see the square brackets that wrap the two objects), delimited by a comma.

Once you’ve created your Tag and published the container, remember to test your site with the Structured Data Testing Tool:

One thing I noticed with the tool is that it doesn’t always work, especially if the HTML of the site is complex. This doesn’t mean the structured data didn’t validate, it just means there was some error in the process.

Remember that since this is GTM, you can use your Variables to make the structured data injector more dynamic. Also, if you’ve defined dataLayer in your page template, and it has information you think would be useful in the structured data markup, you can pull this data using Data Layer Variables within your structured data markup. This means that you can create a really flexible structured data injector by leveraging GTM’s own functionalities.

This feature of Google’s search crawlers has been long in the waiting. It makes so much sense to be able to inject annotations about your content with JavaScript, instead of having them applied directly to the page template by the CMS. Also, the fact that you can inject the object anywhere, not just in the <head> of the document, is a great asset, since GTM, by default, injects to the end of the <body>.