On blog pages, breadcrumbs can be used to make it easier for users to understand and explore your blog effectively by following the trail. Unfortunately hugo doesn’t have a built-in function to display a breadcrumb list. But by using the partial breadcrumb template provided in the hugo documentation, we can easily add breadcrumbs to any blog page built using hugo.

Here is a partial breadcrumb template that I have modified to suit the schema.org structured data. To fill the position’s value, i just need to get the length of splitted url (current page permalink).

<ol itemscope itemtype="https://schema.org/BreadcrumbList" class="breadcrumbs">
    {{ template "breadcrumbs" (dict "p1" . "p2" .) }}
</ol>
{{ define "breadcrumbs" }}
{{ if .p1.Parent }}
{{ template "breadcrumbs" (dict "p1" .p1.Parent "p2" .p2 ) }}
{{ else if not .p1.IsHome }}
{{ template "breadcrumbs" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
{{ end }}

{{ $position := len (split (replace .p1.Permalink ("/" | absURL) "") "/") }}

<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a {{if not (eq .p1.Kind "page") }}
            itemscope itemtype="https://schema.org/WebPage"
            itemprop="item" itemid="{{ .p1.Permalink }}"
        {{ else }}
            itemprop="item" 
        {{ end }}
        href="{{ .p1.Permalink }}">
    	<span itemprop="name">{{ .p1.Title }}</span>
    </a>
    <meta itemprop="position" content="{{$position}}" />
</li>
{{ end }}

To using it with i18n change absURL to absLangURL and all frontmatter can be accessed from .p1 variable. You can save the above code in the file breadcrumbs.html in the layout/partials folder, then place it wherever you need it:

{{- partial "breadcrumbs.html" . -}}

Structured data With json

And For the ld-json structured data, you can add the following code inside the <head> tag:

{{ define "breadcrumbsld" }}
    {{ if .p1.Parent }}
      {{ template "breadcrumbsld" (dict "p1" .p1.Parent "p2" .p2 ) }}
    {{ else if not .p1.IsHome }}
      {{ template "breadcrumbsld" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
    {{ end }}

    {{ $position := len (split (replace .p1.Permalink ("/" | absURL) "") "/") }}

    {
      "@type": "ListItem",
      "position": {{ $position }},
      "item": {{.p1.Permalink }},
      "name": {{ .p1.Title }}
      }
    }{{ if not (eq .p1 .p2 ) }},{{ end }}

{{ end }}

<script type="application/ld+json">
[
  {
    "@context": "http://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [{{- template "breadcrumbsld" (dict "p1" . "p2" .) -}}]
  }
]
</script>