Breadcrumbs Duplication

After quite a while searching I’ve found this article with a very nice way to implement Breadcrumbs with Hugo.

I modified it a little bit to not add links to every part and make use of i18n (since I think I wouldn’t be able to access FrontMatters from here) but also to apply a small workaround to remove some unwanted trails that didn’t match a translated entry:

{{- $url := replace .Permalink ( printf "%s" ( "/" | absLangURL ) ) "" -}}
{{- $url := replace .Permalink ( printf "%s" ( "/" | absLangURL ) ) "" -}}
{{- $.Scratch.Add "path" ( "/" | absLangURL ) -}}

{{- $.Scratch.Add "breadcrumb" (slice (dict "url" ( "/" | absLangURL ) "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>

<nav class="breadcrumb">
  {{- $length := len ($.Scratch.Get "breadcrumb") -}}

  {{- range $index, $.Scratch.Get "breadcrumb" -}}

    <!--
    Assigning a constant as default value for i18n function
    if it doesn't match any entry
    Then check if current Breadcrumb item matches this constant,
    which means that part shouldn't be one of Breadcrumb's trail
    -->
    {{- $i18n := i18n ( print "breadcrumbs-" .name ) | default "__INTERNAL__" -}}

    {{- if not ( eq ($i18n) "__INTERNAL__" ) -}}

      {{ if eq ( (int .position) ) $length }}
  <span class="breadcrumb-item active">{{ $i18n }}</span>
      {{- else -}}
  <a class="breadcrumb-item" href="{{ .url }}" >{{ $i18n }}</a>
      {{- end -}}

    {{- end -}}

  {{ end }}
</nav>

It worked nicely when viewing the site with a language parameter present in URL (i.e. /pt, /fr, /jp…) but when accessing the default language (en), that doesn’t appear in the URL, everything gets duplicated.

First I thought it could be the fact .Site.BaseURL was being used so I replaced it with ( "/" | absLangURL ) but it didn’t change anything.

Any assistance with this?

I suspect that article is fairly old. With the latest Hugo this should be simpler. There have been postings about it in here.

So… 1) if this article is old 2) this have been discussed here 3) I have searched and tried every implementation of all other questions regarding this matter I could find 4) I am using the latest version - and this still doesn’t work, what should I do then? (ง’̀-'́)ง

Although I don’t think so, after all the breadcrumbs work beforenavigating through the Pagination, here’s my content directory structure if that matters at all:

\-\videos
  |-\videos\season-1
  | |-\videos\season-1\01.en.md
  | |-\videos\season-1\01.pt.md
  | |-\videos\season-1\02.en.md
  | |-\videos\season-1\02.pt.md
  | |-\videos\season-1\03.en.md
  | |-\videos\season-1\03.pt.md
  | |-\videos\season-1\04.en.md
  | |-\videos\season-1\04.pt.md
  | |-\videos\season-1\05.en.md
  | |-\videos\season-1\05.pt.md
  | |-\videos\season-1\06.en.md
  | |-\videos\season-1\06.pt.md
  | |-\videos\season-1\07.en.md
  | |-\videos\season-1\07.pt.md
  | |-\videos\season-1\08.en.md
  | |-\videos\season-1\08.pt.md
  | |-\videos\season-1\09.en.md
  | |-\videos\season-1\09.pt.md
  | |-\videos\season-1\10.en.md
  | |-\videos\season-1\10.pt.md
  | |-\videos\season-1\11.en.md
  | |-\videos\season-1\11.pt.md
  | |-\videos\season-1\12.en.md
  | |-\videos\season-1\12.pt.md
  | |-\videos\season-1\13.en.md
  | |-\videos\season-1\13.pt.md
  | |-\videos\season-1\14.en.md
  | |-\videos\season-1\14.pt.md
  | |-\videos\season-1\15.en.md
  | |-\videos\season-1\15.pt.md
  | |-\videos\season-1\16.en.md
  | |-\videos\season-1\16.pt.md
  | |-\videos\season-1\17.en.md
  | |-\videos\season-1\17.pt.md
  | |-\videos\season-1\18.en.md
  | |-\videos\season-1\18.pt.md
  | |-\videos\season-1\19.en.md
  | |-\videos\season-1\19.pt.md
  | |-\videos\season-1\20.en.md
  | |-\videos\season-1\20.pt.md
  | |-\videos\season-1\21.en.md
  | |-\videos\season-1\21.pt.md
  | |-\videos\season-1\22.en.md
  | |-\videos\season-1\22.pt.md
  | |-\videos\season-1\23.en.md
  | |-\videos\season-1\23.pt.md
  | |-\videos\season-1\24.en.md
  | |-\videos\season-1\24.pt.md
  | |-\videos\season-1\25.en.md
  | |-\videos\season-1\25.pt.md
  | |-\videos\season-1\26.en.md
  | |-\videos\season-1\26.pt.md
  | |-\videos\season-1\27.en.md
  | |-\videos\season-1\27.pt.md
  | |-\videos\season-1\28.en.md
  | |-\videos\season-1\28.pt.md
  | |-\videos\season-1\29.en.md
  | |-\videos\season-1\29.pt.md
  | |-\videos\season-1\30.en.md
  | |-\videos\season-1\30.pt.md
  | |-\videos\season-1\31.en.md
  | |-\videos\season-1\31.pt.md
  | |-\videos\season-1\32.en.md
  | |-\videos\season-1\32.pt.md
  | |-\videos\season-1\33.en.md
  | |-\videos\season-1\33.pt.md
  | |-\videos\season-1\34.en.md
  | |-\videos\season-1\34.pt.md
  | |-\videos\season-1\35.en.md
  | |-\videos\season-1\35.pt.md
  | |-\videos\season-1\36.en.md
  | |-\videos\season-1\36.pt.md
  | |-\videos\season-1\37.en.md
  | |-\videos\season-1\37.pt.md
  | |-\videos\season-1\38.en.md
  | |-\videos\season-1\38.pt.md
  | |-\videos\season-1\39.en.md
  | |-\videos\season-1\39.pt.md
  | |-\videos\season-1\40.en.md
  | |-\videos\season-1\40.pt.md
  | |-\videos\season-1\_index.en.md
  | \-\videos\season-1\_index.pt.md
  |-\videos\season-1.en.md
  |-\videos\season-1.pt.md
  |-\videos\season-2
  | |-\videos\season-2\01.en.md
  | |-\videos\season-2\01.pt.md
  | |-\videos\season-2\02.en.md
  | |-\videos\season-2\02.pt.md
  | |-\videos\season-2\03.en.md
  | |-\videos\season-2\03.pt.md
  | |-\videos\season-2\04.en.md
  | |-\videos\season-2\04.pt.md
  | |-\videos\season-2\05.en.md
  | |-\videos\season-2\05.pt.md
  | |-\videos\season-2\06.en.md
  | |-\videos\season-2\06.pt.md
  | |-\videos\season-2\07.en.md
  | |-\videos\season-2\07.pt.md
  | |-\videos\season-2\08.en.md
  | |-\videos\season-2\08.pt.md
  | |-\videos\season-2\09.en.md
  | |-\videos\season-2\09.pt.md
  | |-\videos\season-2\10.en.md
  | |-\videos\season-2\10.pt.md
  | |-\videos\season-2\11.en.md
  | |-\videos\season-2\11.pt.md
  | |-\videos\season-2\12.en.md
  | |-\videos\season-2\12.pt.md
  | |-\videos\season-2\13.en.md
  | |-\videos\season-2\13.pt.md
  | |-\videos\season-2\14.en.md
  | |-\videos\season-2\14.pt.md
  | |-\videos\season-2\15.en.md
  | |-\videos\season-2\15.pt.md
  | |-\videos\season-2\16.en.md
  | |-\videos\season-2\16.pt.md
  | |-\videos\season-2\17.en.md
  | |-\videos\season-2\17.pt.md
  | |-\videos\season-2\18.en.md
  | |-\videos\season-2\18.pt.md
  | |-\videos\season-2\19.en.md
  | |-\videos\season-2\19.pt.md
  | |-\videos\season-2\20.en.md
  | |-\videos\season-2\20.pt.md
  | |-\videos\season-2\21.en.md
  | |-\videos\season-2\21.pt.md
  | |-\videos\season-2\22.en.md
  | |-\videos\season-2\22.pt.md
  | |-\videos\season-2\23.en.md
  | |-\videos\season-2\23.pt.md
  | |-\videos\season-2\24.en.md
  | |-\videos\season-2\24.pt.md
  | |-\videos\season-2\25.en.md
  | |-\videos\season-2\25.pt.md
  | |-\videos\season-2\26.en.md
  | |-\videos\season-2\26.pt.md
  | |-\videos\season-2\27.en.md
  | |-\videos\season-2\27.pt.md
  | |-\videos\season-2\_index.en.md
  | \-\videos\season-2\_index.pt.md
  |-\videos\season-2.en.md
  |-\videos\season-2.pt.md
  |-\videos\season-3
  | |-\videos\season-3\01.en.md
  | |-\videos\season-3\01.pt.md
  | |-\videos\season-3\02.en.md
  | |-\videos\season-3\02.pt.md
  | |-\videos\season-3\03.en.md
  | |-\videos\season-3\03.pt.md
  | |-\videos\season-3\04.en.md
  | |-\videos\season-3\04.pt.md
  | |-\videos\season-3\05.en.md
  | |-\videos\season-3\05.pt.md
  | |-\videos\season-3\06.en.md
  | |-\videos\season-3\06.pt.md
  | |-\videos\season-3\07.en.md
  | |-\videos\season-3\07.pt.md
  | |-\videos\season-3\08.en.md
  | |-\videos\season-3\08.pt.md
  | |-\videos\season-3\09.en.md
  | |-\videos\season-3\09.pt.md
  | |-\videos\season-3\10.en.md
  | |-\videos\season-3\10.pt.md
  | |-\videos\season-3\11.en.md
  | |-\videos\season-3\11.pt.md
  | |-\videos\season-3\12.en.md
  | |-\videos\season-3\12.pt.md
  | |-\videos\season-3\_index.en.md
  | \-\videos\season-3\_index.pt.md
  |-\videos\season-3.en.md
  |-\videos\season-3.pt.md
  |-\videos\trivias
  | |-\videos\trivias\01.en.md
  | |-\videos\trivias\01.pt.md
  | |-\videos\trivias\02.en.md
  | |-\videos\trivias\02.pt.md
  | |-\videos\trivias\03.en.md
  | |-\videos\trivias\03.pt.md
  | |-\videos\trivias\04.en.md
  | |-\videos\trivias\04.pt.md
  | |-\videos\trivias\05.en.md
  | |-\videos\trivias\05.pt.md
  | |-\videos\trivias\06.en.md
  | |-\videos\trivias\06.pt.md
  | |-\videos\trivias\07.en.md
  | |-\videos\trivias\07.pt.md
  | |-\videos\trivias\08.en.md
  | |-\videos\trivias\08.pt.md
  | |-\videos\trivias\_index.en.md
  | \-\videos\trivias\_index.pt.md
  |-\videos\trivias.en.md
  |-\videos\trivias.pt.md
  |-\videos\_index.en.md
  \-\videos\_index.pt.md

Thanks @magnusthorek , i use snippet provided in hugo documentation page, i modified it using len to figuring out the length of splitted url to get the $position.

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

in my case it work using absURL.