Implementing breadcrumb navigation in hugo?

Use Permalink or RelPermalink for … linking.

The original poster has defined the currentPage key with dict
{{ template "breadcrumb" dict "currentPage" .Page "id" .UniqueID }}

If one uses .Permalink as you suggest the parent pages will have the current page’s URL.

Just tried it out.

That was not what I said.

Right. Sorry. I misunderstood your comment.

Now I think I got it. You meant this:

<a href="{{ .currentPage.Permalink }}">{{ .currentPage.Title }}</a> >

OR

<a href="{{ .currentPage.RelPermalink }}">{{ .currentPage.Title }}</a> >

Is that right?

1 Like

Yes.

In short, the URL is the raw URL definition of the page, and should probably unexported, but that would probably break more than it would help. But my point is that URL may in many cases differ from RelPermalink, which will be bad if you use it in a theme.

1 Like

Links of this implementation way up the chain is all messed up for me.

URL like http://localhost:1313/videos/season-1/ outputs a list of three items with links as http://localhost:1313/, http://localhost:1313/videos/season-1//http://localhost:1313/videos and http://localhost:1313/videos/season-1//http://localhost:1313/videos/season-1 respectively.

Currently trying to make this code work with this one, that’s way more elegant and have working URLs but duplicates content.

I know this is an old thread, but I have just bumped into this issue of having the URL duplicated for every child page and not sure why it’s happening? Linked copied from @magnusthorek link above: https://gohugohq.com/partials/breadcrumb-partial-with-structured-data-in-hugo

{{ $url := replace .Permalink ( printf "%s" .Site.BaseURL) "" }}
{{ $.Scratch.Add "path" .Site.BaseURL }}

{{ $.Scratch.Add "breadcrumb" (slice (dict "url" .Site.BaseURL "name" "home" "position" 1 )) }}
{{ range $index, $element := split $url "/" }}
{{ $.Scratch.Add "path" $element }}
{{ $.Scratch.Add "path" "/" }}
{{ if ne $element "" }}
{{ $.Scratch.Add "breadcrumb" (slice (dict "url" ($.Scratch.Get "path") "name" . "position" (add $index 2))) }}
{{ end }}
{{ end }}

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{{ range $.Scratch.Get "breadcrumb" }}{{ if ne .position 1 }},{{ end }}{
        "@type": "ListItem",
        "position": {{ .position }},
        "item": {
          "@id": "{{ .url }}",
          "name": "{{ .name }}"
        }
    }{{ end }}]
}
</script>

"@id": “{{ .url }}” give me this:

http://localhost:1313/about/http://localhost:1313/about/
http://localhost:1313/contact/http://localhost:1313/contact/
http://localhost:1313/blog/blog-post3/http://localhost:1313/blog/blog-post3/

I can’t say for sure that this will solve your problem because I changed the way I do mine when I started using Custom URLs with which, obviously, this code doesn’t work since there are little to none URL components to be analyzed.

As much as I can tell from this old commit I’ve found (lucky you :p), what I did to solve the problem back then was to initialize a Template Variable with the scope of the “dot” that’s passed to the Partial Template and instead of calling the Scratch from the context of the dollar-sign (or whatever it’s called in Hugo/Go) I used this variable I initialized.

Here:

{{ $dot := . }}
{{ $dot.Scratch.Set "path" "" }}
{{ $dot.Scratch.Set "breadcrumb" slice }}

And, instead of, for example:

{{ $.Scratch.Add "path" $element }}

I used:

{{ $dot.Scratch.Add "path" $element }}

And all Pagination elements worked without duplicates.

YES! Finally got it to work thanks to your code changes, this is what I have ended up with incase someone needs it. Since I am new to HUGO not sure if the below code could be improved but it works for now. Thank you @magnusthorek

{{ $dot := . }}
{{ $dot.Scratch.Set "path" "" }}
{{ $dot.Scratch.Set "breadcrumb" slice }}

{{ $url := replace .Permalink ( printf "%s" .Site.BaseURL) "" }}
{{ $.Scratch.Add "path" .Site.BaseURL }}

{{ $.Scratch.Add "breadcrumb" (slice (dict "url" .Site.BaseURL "name" "home" "position" 1 )) }}
  {{ range $index, $element := split $url "/" }}
    {{ $dot.Scratch.Add "path" $element }}
    {{ $.Scratch.Add "path" "/" }}
    {{ if ne $element "" }}
    {{ $.Scratch.Add "breadcrumb" (slice (dict "url" ($.Scratch.Get "path") "name" . "position" (add $index 2))) }}
  {{ end }}
{{ end }}

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{{ range $.Scratch.Get "breadcrumb" }}{{ if ne .position 1 }},{{ end }}{
        "@type": "ListItem",
        "position": {{ .position }},
        "item": {
          "@id": "{{ .url }}",
          "name": "{{ .name }}"
        }
    }{{ end }}]
}
</script>

@magnusthorek sorry, just realised that the pagination is not outputted as position 3, so if I have:
Home - Blog - Page 3 I only see Home - Blog even if I am on `page 3, my taxonomies work just perfectly.:thinking:

This approach (@maltesa/@alexandros 's) is not working for me for taxonomyterm lists. I would expect the breadcrumb nav on https://site.com/categories/foo to be home > categories > foo, but instead it shows only home > foo.

Any ideas on how to fix that?

Can you point us to source code so that we can test it locally, please?

Any idea how to change the . in the following statement

{{ $.Scratch.Add "breadcrumb" (slice (dict "url" ($.Scratch.Get "path") "name" . "position" (add $index 2))) }}

so that it instead displays the title of the page? If I change . to .Title I get the following error message:

error calling partial: template: partials/breadcrumb.html:9:79: executing "partials/breadcrumb.html" at <.Title>: can't evaluate field Title in type string

Using title . or a similar function won’t work well for my needs. Thanks.

	<nav aria-label="breadcrumb">
		<ol class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList">
		
		<li class="breadcrumb-item" itemprop="itemListElement" itemscope
			itemtype="http://schema.org/ListItem">

			<a href="{{  .Site.BaseURL  }}" itemprop="item">
				<span itemprop="name">
					Home
				</span>
				<meta itemprop="position" content="1" />
			</a>

		</li>

	{{ $findUrl := slice }}

	{{ range $index, $el := (split .URL "/") }}
	{{ if gt (len . ) 0 }}

	{{ $findUrl = uniq ($findUrl | append .) | sort }}

	{{ end }}
	{{ end }}

	{{ $url := "/" }}
	{{ range $index, $el := $findUrl }}

	<li class="breadcrumb-item" itemprop="itemListElement" itemscope
	itemtype="http://schema.org/ListItem">
	{{ $url = "/" | add . | add $url  }}

	<a href="{{ $url }}"  itemprop="item">
			<span itemprop="name"> {{ . }} </span>
			{{ $index = $index | add 2 }}
			<meta itemprop="position" content="{{ $index }}" />
		</a>
	</li>
	{{ end }}


	</nav>

	<!-- END breadcrumbs -->
1 Like