DEV Community

Dwarkanath Prabhu
Dwarkanath Prabhu

Posted on

Adding Structured Data to your Hugo site

If you search for a popular topic on Google, you can see some news articles displayed prominently at the top of Google Search Results. Like this:

Google recognizes that a certain page on the web is an article and more specifically an article related to the topic you searched because the publisher (like Times of India in this case) has added structured data to their pages. Structured Data is a set of rules to inform search engines what a particular page on your website is all about.

There are some obvious benefits to adding Structured Data to your website. You can see above that articles with structured data look different from normal search results i.e. there is a publisher name (like Times of India), thumbnail image, summary etc. They take up more space than normal search results and more importantly, these results are featured on top of search results giving them maximum visibility. More visibility in search results means more clicks and traffic to your website.

If you have a blog, your posts will be of the type "Article" or "BlogPosting". The necessary structured data Google needs for an article is mentioned on their website here:

The complete list of rules (for all kinds of pages) can be found on the official Schema documentation website:

Now, writing structured data for every page on your website is tedious especially if each page is about a different topic. Fortunately, static site generators allow you to create your own partials i.e. pieces of HTML code that are repeated across the site. By allowing some variables in partials, it is possible to have unique schema for all of your pages. Follow the steps below to do exactly this.

Crate a schema.html file

If you have a static site built using Hugo, all you need to do is create a partial called schema.html. Google recommends you write the structured data in JSON-LD. You don't need to know much about JSON-LD. Just copy the code snippets below as they are and you're golden 😛

<script type="application/ld+json">
{{ if eq .Section "posts" }}
  "@context": "",
  "@type": "BlogPosting",
  "headline": {{ .Title }},
  "image": {{ .Params.featuredImage | absURL }},
  "datePublished": {{ .PublishDate }},
  "dateModified": {{ .Lastmod }},
  "author": {
    "@type": "Person",
    "name": {{ }}
  "mainEntityOfPage": { "@type": "WebPage" },
   "publisher": {
    "@type": "Organization",
    "name": {{ .Site.Params.header }},
    "logo": {
      "@type": "ImageObject",
      "url": {{ .Site.Params.logo }}
  "description": {{ .Summary | plainify | safeHTML }},
  "keywords": [{{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}]
{{ end }}
  "@context": "",
  "@type": "Organization",
  "name": {{ .Site.Params.header }},
  "url": {{ .Site.BaseURL }},
  "sameAs": [
    "{{ .Site.Params.facebook }}",
    "{{ .Site.Params.instagram }}",
    "{{ .Site.Params.twitter }}",
    "{{ .Site.Params.github }}"
Enter fullscreen mode Exit fullscreen mode

This file needs to be in your theme's partials folder.

Add variable values to config file

In your site's config.toml file, you will need to add the values of variables that you have used in schema.html file above. For my website, WeekInMemes, I would use my own name as author, social media handles etc. For your website replace those with your own values.

baseURL = ""

author = "DK"
logo = "img/logo.jpg"
header = "Week In Memes"

facebook = "weekinmemes"
twitter = "weekinmemes"
instagram = "weekinmemes"
github = "weekinmemes"
Enter fullscreen mode Exit fullscreen mode

Add partial to head tag

Finally you will need to add this partial somewhere in your <head> tag. Usually your Hugo theme will have a head.html partial where you can add the following line before closing the <head> tag:

{{ partial schema.html . }}
Enter fullscreen mode Exit fullscreen mode


Once you have all these in place, you can use your regular building commands (hugo -D or hugo server -D) to see the HTML files generated.

Use the Structured Data Testing Tool by Google to test if Google is reading everything correctly. It should point out errors, if any, that you may need to correct.

That's it!

Top comments (3)

virtual profile image
Jeanine Schoessler

Thank you for putting this together! The only thing I'm not sure about is that the Google Structured Data testing tool currently only sees the two (Organization and Blog Post) types when I put them in two separate <script> tags so I updated my code to include a closing/opening tag.

alternativervb profile image
Alternative RVB

Cool, je vais essayer cela très prochainement

ignatha profile image
Ignatha Prabowo

its work in my hugo website