Home > Categories > Hugo > Breadcrumb JSON LD Structured Data in Hugo Partial Template

Home > Breadcrumb JSON LD Structured Data in Hugo Partial Template

Breadcrumb JSON LD Structured Data in Hugo Partial Template

Updated:

28 Feb 2021

Published:

1 Jan 2020

The fastest way to get unlimited traffic from google is to do something that is good for google search users and good for google as business.

If you properly provide breadcrumb on every page then it helps google search users and visitors of your website to navigate website more effectively.

And with breadcrumb google can optimize their cost associated with crawling your website. Basically you make google's job easier and cheaper.

There is no direct corelation of increase in traffic because of breadcrumb. But indirectly it affects amount of time spent on your website and helps users find content quicker.

Like google always says "Make website for people not for search engines".

To read rest of the article please Purchase Subscription

Before adding structured data I would recommend to develop hugo website inside development docker container.

So we no longer have the issue of "this works on my computer". And it will not mess with your existing workflow.

So checkout my blog post for detailed video explanation.

Whenever adding structured data it is very important to read google search documentation instead of just using Schema.org.

Because according to google documentation

You should rely on the documentation on developers.google.com as definitive for Google Search behavior, rather than the schema.org documentation. Attributes or objects not described here are not required by Google Search, even if marked as required by schema.org.

If you add all possible structured data then you are basically helping google do their job of understanding about your website.

Just because google understands your website doesn't mean you will get more traffic. So only add necessary attributes specified by google.

So this blog post is biased towards google search compatibility. And it may or may not work with other search engines.

I am going to use JSON-ld for writing structured data. Again because google recommends using JSON-ld whenever possible.

For breadcrumbs you can generate everything you need with using .Permalink.

Just create new partial template and add the following code.

Let me explain block by block

1
2
3
4
5
6
7
{{ $url := replace .Permalink (printf "%s" .Site.BaseURL) ""}}
{{ .Scratch.Add "path" .Site.BaseURL }}
{{ .Scratch.Add "breadcrumb" (slice (dict "url" .Site.BaseURL "name" "Home"))}}
{{ .Scratch.Add "permalink" .Permalink }}
{{ .Scratch.Add "title" .Title }}
{{ $pScratch := .Scratch }}
  

I make extensive use of scratch so if you are not familiar with scratch then read official scratch documentation or read helpful post by Regis Philibert about scratch explained before moving forward.

Basically once you get inside range (golang version of for loops) then you lose access to all local variables.

So you save variables in temporary scratch pad that you can access inside range/for loop.

Line 2 I removed the base url e.g. https://example.com/ from the page url and store it into url variable

In rest of the code I have simply saved variables in scratch

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{{ range $index, $element := split $url "/" }}
  {{ $pScratch.Add "path" $element }}
  {{ $pScratch.Add "path" "/" }}
  {{ if ne $element "" }}
    {{ if eq ($pScratch.Get "path") ($pScratch.Get "permalink") }}
        {{ $pScratch.Add "breadcrumb" (slice (dict "url" ($pScratch.Get "path") "name" ($pScratch.Get "title")))}}
    {{ else }}
        {{ $pScratch.Add "breadcrumb" (slice (dict "url" ($pScratch.Get "path") "name" (humanize .)))}}
    {{ end }}
  {{ end }}
{{ end }}
  

Then we break down the url path and save inside scratch.

If the url is the final page url then for name we set the title of the page.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
    <script type="application/ld+json">
      [{
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
          {{ range $index, $breadcrumb := .Scratch.Get "breadcrumb" }}
            {{ if ne $index 0 }},{{ end }}
              {
                "@type": "ListItem",
                "position": {{ add $index 1 }},
                "name": "{{ $breadcrumb.name }}",
                {{ if ne $breadcrumb.url ($pScratch.Get "permalink") }}
                  "item": {{ printf "%s" $breadcrumb.url }},
                {{ end }}
              }
          {{ end }}
          ]
        }
    

So in this part we are adding setting breadcrumb based on the url.

One mistake I made in past was I only added breadcrumb structured data and never added links on the page. Don't make this mistake.

If you add something in the structured data then you should add similar content on the page also.

On page for breadcrumb links you won't add link to your current page in the breadcrumb. But you would add links to home page and other root pages that came before this page.

We do the same for structured data also. We don't add link to current page in structured data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    {{ range $index, $category :=  .Params.categories }}
      ,
      {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
          {
            "@type": "ListItem",
            "position": 1,
            "name": "Home",
            "item": "{{$.Site.BaseURL}}",
          },
          {
            "@type": "ListItem",
            "position": 2,
            "name": "Categories",
            "item": "{{$.Site.BaseURL}}categories/",
          },
          {
            "@type": "ListItem",
            "position": 3,
            "name": "{{ humanize . }}",
            "item": "{{$.Site.BaseURL}}categories/{{.}}",
          },
          {
            "@type": "ListItem",
            "position": 4,
            "name": "{{ $pScratch.Get "title" }}",
          },
        ]
      }
    {{ end }}
    ]
</script>

You may add may different categories or tags to your blog post. So I have provided alternate breadcrumb for each category.

Then you need to show same links on single NOT on list pages.

So first I show all category breadcrumb then show breadcrumb based on page Url.

Don't add variables again to the scratch pad. You can reuse the same scratch pad from different partials.

I have added all variables in partial that is added in the head of the page then accessed them in partial that is in body of the page.

After deploying website don't forget to test with Structured Data Testing Tool to check for any errors. Fix them as per google's suggestion.

Free users cannot comment below so if you have questions then tweet me @apoorvmote. I would really like to hear your brutally honest feedback.

If you like this article please consider purchasing paid