Generating Breadcrumbs for Hugo

Hugo v0.109.0 “added a new .Ancestors method on Page that walks up the tree to the home page. With this, breadcrumbs templates can be greatly simplified”. Below is a simple example of breadcrumbs that I use on my site.

<nav class="" aria-label="breadcrumbs">
    <ol class="">
        {{- range .Ancestors.Reverse }}
      <li class="">
        <a href="{{ .RelPermalink }}">{{ if .IsHome }}{{ i18n "home" }}{{ else }}{{ .Title }}{{ end }}</a>
      </li>
      <span class="" aria-hidden="true">»</span>
      {{- end }}
      <li class="active">
        <a href="{{ .RelPermalink }}" aria-current="location">{{ .Title }}</a>
      </li>
    </ol>
  </nav>

If your site is multilingual, define {{ i18n "home" }} in your i18n folder with the respective language equivalent for Homepage or whatever you fancy. If your site is not multilingual, replace {{ i18n "home" }} with an SVG Icon, text (Home etc.) or whatever word you fancy. Cheers!

7 Likes

I tuned this code snippet to make the breadcrumbs consistent with Schema.org structured data and rich Google results. Thanks to the .Ancestor method, the breadcrumb code is much simpler and more readable than before.

	<ol class="" itemscope itemtype="https://schema.org/BreadcrumbList">
        {{- /* declare a 'variable' to store the each link position */}}
        {{- $data := newScratch }}

        {{- range $index, $value := .Ancestors.Reverse }}
            <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
                {{- /* read the index from loop and add 'one', because it starts counting from zero */}}
                {{- $data.Set "counter" $index }}
                {{- $data.Add "counter" 1 }}
                <a itemprop="item" href="{{.Permalink}}">
                    <span itemprop="name">{{.Title}}</span>
                </a>
                {{- /* pass the counter value into schema attribute */}}
                <meta itemprop="position" content='{{ $data.Get "counter"}}' />
            </li>         
        {{- end }}
            <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
                {{- /* add 'one' one more time for the last link position */}}
                {{- $data.Add "counter" 1 }}
                <a itemprop="item" href="{{ .Permalink }}">
                    <span itemprop="name">{{.Title}}</span>
                </a>
                {{- /* pass the counter value into schema attribute */}}
                <meta itemprop="position" content='{{ $data.Get "counter"}}' />
            </li>
    </ol>
5 Likes

Sweet merciful go gods this is really handy. I had a convoluted mess until I found .Ancestors!

If anyone needs a schema.org JSON-LD version of this:

{{ if not .IsHome }}
      <script type='application/ld+json'>
      {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement":
        [
        {{- $i := 1 }}
        {{- range .Ancestors.Reverse }}
          {
            "@type": "ListItem",
            "position": {{ $i }},
            "name": "{{ .Title | safeJS }}",
            "url": {{ .Permalink }},
            "item": {{ .Permalink }}
          },
          {{- $i = add $i 1 -}}
        {{ end }}
          {
            "@type": "ListItem",
            "position": {{ $i }},
            "name": "{{ .Title | safeJS }}",
            "url": {{ .Permalink }},
            "item": {{ .Permalink }}
          }
        ]
      }
      </script>
{{ end }}
3 Likes