Breadcrumbs: Multiple Collections For Product, Wrong One Displays. How To Fix?

Topic summary

A Shopify store owner is experiencing an issue where breadcrumbs display the wrong collection for products belonging to multiple collections. The system appears to default to alphabetical order (e.g., “Mens/Unisex” shows instead of the preferred “Necklaces” because M comes before N).

Proposed Solutions:

  • Priority-based collection selection: Modify the Liquid code to check against a predefined list of preferred collection handles, selecting the first match instead of relying on alphabetical order
  • Session storage approach: Save the collection when users navigate from a collection page, ensuring the breadcrumb reflects their actual path
  • Metafield method: Create a product metafield to manually specify which collection should appear in breadcrumbs

Current Status:

The original poster attempted implementing the priority-based code but encountered integration issues, resulting in duplicate breadcrumb displays. They’ve requested more specific guidance on where to insert the code within their existing snippet, as their coding knowledge is intermediate level.

Summarized with AI on October 30. AI used: claude-sonnet-4-5-20250929.

Hello all! I’m using a pretty good breadcrumb snippet, it works great for me, but there is one small annoying thing. When some products belong to more than one collection, the collection displayed in the breadcrumb is one I’d rather not show.

For example: if a necklace is in both “Necklaces” and “Mens/Unisex”, instead of “Necklaces” appearing in the breadcrumb (which I would prefer) on the product page, “Mens/Unisex” always does (I assume because it’s alphabetical: M comes before N).

I’m using the Studio theme, 15.0. Is there a way I can somehow choose a “default” collection for products that are in multiple collections? Or perhaps rank collections somehow, in order of priority? Or add tag to the product that can be referenced, to make sure it defaults to a matching category name? Or some other way? I’m only kind of intermediate at stuff like this, and this is definitely over my head.

I’m hoping someone could take a look at the code I’m using, and maybe see if there’s something that could be changed there to help… thank you in advance for any advice you may offer!

{%- unless template == 'index' or template == 'cart' -%}
<nav class="breadcrumb" role="navigation" aria-label="breadcrumbs">
  <a href="/" title="Home">Home</a>  
{%- if template contains 'product' -%}
  {%- capture product_url_string -%}{%- for collection in product.collections -%}{{collection.url }}|{%- endfor -%}{%- endcapture -%}
  {%- assign object_url_string = product_url_string | append: product.url -%}
{%- elsif template contains 'collection' and collection.handle -%}
  {%- capture object_url_string -%}/collections/{{ collection.handle }}{%- endcapture -%}
{%- elsif template contains 'page' -%}
  {%- capture object_url_string -%}/pages/{{ page.url }}{%- endcapture -%}
{% endif %}
{%- assign object_urls = object_url_string | split: '|' -%}   
{%- capture linklist_titles_str -%}{%- for linklist in linklists -%}{{ linklist.title | handleize }}|{%- endfor -%}{%- endcapture -%}
{%- assign str_size = linklist_titles_str | size | minus: 1 -%}
{%- assign linklist_titles_str = linklist_titles_str | slice: 0, str_size -%}
{%- assign linklist_titles = linklist_titles_str | split: '|' -%}
{%- assign level = 1 -%}
{%- for link in linklists.main-menu.links -%}
  {%- assign link_handle = link.title | handle -%}
  {%- assign link_titles = link_titles | append: link.title | append: '|' -%}
  {%- assign link_urls = link_urls | append: link.url | append: '|' -%}
  {%- assign link_levels = link_levels | append: level | append: '|'  -%}
  {%- assign link_parents = link_parents | append: 'main-menu' | append: '|'  -%}
  {%- assign link_handles = link_handles | append: link_handle | append: '|' -%}
  {%- if linklist_titles contains link_handle -%}
   {%- for clink in linklists[link_handle].links -%}
      {%- if forloop.first == true -%}
        {%- assign level = level | plus: 1 -%}
      {%- endif -%}
      {% assign clink_handle = clink.title | handle %}
      {%- assign link_titles = link_titles | append: clink.title | append: '|' -%}
      {%- assign link_urls = link_urls | append: clink.url | append: '|' -%}
      {%- assign link_levels = link_levels | append: level | append: '|'  -%}
      {%- assign link_parents = link_parents | append: link_handle | append: '|'  -%}
      {%- assign handle = link.title | handleize -%} 
      {%- assign link_handles = link_handles | append: clink_handle | append: '|' -%}
      {%- if linklist_titles contains clink_handle -%}
            {%- for gclink in linklists[clink_handle].links -%}
              {%- if forloop.first == true -%}
                {%- assign level = level | plus: 1 -%}
              {%- endif -%}
              {% assign gclink_handle = gclink.title | handle %}
              {%- assign link_titles = link_titles | append: gclink.title | append: '|' -%}
              {%- assign link_urls = link_urls | append: gclink.url | append: '|' -%}
              {%- assign link_levels = link_levels | append: level | append: '|'  -%}
              {%- assign link_parents = link_parents | append: clink_handle | append: '|'  -%}
              {%- assign link_handles = link_handles | append: gclink_handle | append: '|' -%}
              {%- if linklist_titles contains gclink_handle -%}
              {%- endif -%}
              {%- if forloop.last == true -%}
                {%- assign level = level | minus: 1 -%}
              {%- endif -%}
            {%- endfor -%}
      {%- endif -%}
      {%- if forloop.last == true -%}
        {%- assign level = level | minus: 1 -%}
      {%- endif -%}
    {%- endfor -%}
  {%- endif -%}
{%- endfor -%}
{%- assign str_size = link_levels | size | minus: 1 -%}
{%- assign llevels = link_levels | slice: 0, str_size | split: '|' -%} 
{%- assign str_size = link_titles | size | minus: 1 -%}
{%- assign ltitles = link_titles | slice: 0, str_size | split: '|' -%} 
{%- assign str_size = link_handles | size | minus: 1 -%}
{%- assign lhandles = link_handles | slice: 0, str_size | split: '|' -%}
{%- assign str_size = link_parents | size | minus: 1 -%}
{%- assign lparents = link_parents | slice: 0, str_size | split: '|' -%}
{%- assign str_size = link_urls | size | minus: 1 -%}
{%- assign lurls = link_urls | slice: 0, str_size | split: '|' -%}
{%- assign depth = '3' -%}
{%- assign bc3_parent_list_handle = '' %}
{%- comment -%} Do we have a link to this product or its collection on the deepest level? {%- endcomment -%}
{%- for url in lurls -%}
  {%- if object_urls contains url and llevels[forloop.index0] == depth -%}
    {%- unless url == product.url or url == collection.url -%}
      {%- capture bc3 -%}{{ ltitles[forloop.index0] | link_to: url, ltitles[forloop.index0] }}{%- endcapture -%}
    {%- endunless -%}
    {%- assign bc3_parent_list_handle = lparents[forloop.index0] -%}
    {%- assign bc3_list_handle = lhandles[forloop.index0] -%}
    {% break %}
  {%- endif -%}
{%- endfor -%}
{%- assign depth = '2' -%}
{%- assign bc2_parent_list_handle = '' %}
{%- if bc3_parent_list_handle == '' -%} 
  {%- for url in lurls -%}
    {%- if llevels[forloop.index0] == depth -%}
      {%- if object_urls contains url -%} 
        {%- unless url == product.url or url == collection.url -%}
          {%- capture bc2 -%}{{ ltitles[forloop.index0] | link_to: url, ltitles[forloop.index0] }}{%- endcapture -%}
        {% endunless %}
        {%- assign bc2_parent_list_handle = lparents[forloop.index0] -%}
        {%- break -%}
      {%- endif -%}
    {%- endif -%}
  {%- endfor -%} 
{%- else -%}
  {%- for list_handle in lhandles -%}
    {%- if list_handle == bc3_parent_list_handle -%}
      {% assign bc2_list_handle = list_handle %}
      {%- assign bc2_parent_list_handle = lparents[forloop.index0] -%}
      {%- assign bc2_list_title = ltitles[forloop.index0] -%}
      {%- for bc2_sibling_link in linklists[bc2_parent_list_handle].links -%}
        {%- assign bc2_sibling_title_handleized = bc2_sibling_link.title | handle -%}
        {% if bc2_sibling_title_handleized == bc2_list_handle %}
          {%- capture bc2 -%}{{ bc2_sibling_link.title | link_to: bc2_sibling_link.url, bc2_sibling_link.title }}{%- endcapture -%}
          {% break %}
        {%- endif -%}
      {%- endfor -%}
      {% break %}
    {%- endif -%}
  {%- endfor -%}
{%- endif -%}
{%- assign depth = depth | minus: 1 | append: '' -%}
{%- assign bc1_parent_list_handle = '' %}
{%- if bc2_parent_list_handle == '' -%} 
  {% for url in lurls %}
    {%- if object_urls contains url and llevels[forloop.index0] == depth -%}
      {%- unless url == product.url or url == collection.url -%}
        {%- capture bc1 -%}{{ ltitles[forloop.index0] | link_to: url, ltitles[forloop.index0] }}{%- endcapture -%}
      {% endunless %}
      {%- assign bc1_parent_list_handle = lparents[forloop.index0] -%}
      {%- break -%}
    {%- endif -%}
  {%- endfor -%}
{%- else -%}
  {%- for list_handle in lhandles -%}
    {%- if bc2_parent_list_handle == list_handle -%}
      {% assign bc1_list_handle = list_handle %}
      {%- assign bc1_parent_list_handle = lparents[forloop.index0] -%}
      {%- assign bc1_title = ltitles[forloop.index0] -%}            
      {%- for bc1_sibling_link in linklists[bc1_parent_list_handle].links -%}
        {%- assign bc1_sibling_title_handleized = bc1_sibling_link.title | handle -%}
        {% if bc1_sibling_title_handleized == bc1_list_handle %}
          {%- capture bc1 -%}{{ bc1_sibling_link.title | link_to: bc1_sibling_link.url, bc1_sibling_link.title }}{%- endcapture -%} 
          {% break %}
        {%- endif -%}
      {%- endfor -%}
    {%- endif -%}
  {%- endfor -%}
{%- endif -%} 
  {%- if bc1 -%}
    <span aria-hidden="true">›</span>
    {{ bc1 }}
  {%- endif -%}
  {%- if bc2 -%}
    <span aria-hidden="true">›</span>
    {{ bc2 }}
  {%- endif -%}
  {%- if bc3 -%}
    <span aria-hidden="true">›</span>
    {{ bc3 }}
  {%- endif -%}
{%- if template contains 'product' -%}
  <span aria-hidden="true">›</span>
  <span>{{ product.title }}</span> 
{%- elsif template contains 'collection' and collection.handle -%}
    <span aria-hidden="true">›</span>
    <span>{{ collection.title }}</span> 
{%- elsif template == 'blog' -%} 
  <span aria-hidden="true">›</span>
  {%- if current_tags -%}
    {{ blog.title | link_to: blog.url }}
    <span aria-hidden="true">›</span>
    <span>{{ current_tags | join: " + " }}</span>
  {%- else -%}
  <span>{{ blog.title }}</span>
  {%- endif -%} 
{%- elsif template == 'article' -%} 
  <span aria-hidden="true">›</span>
  {{ blog.title | link_to: blog.url }}
  <span aria-hidden="true">›</span>
  <span>{{ article.title }}</span> 
{%- elsif template contains 'page' -%} 
 <span aria-hidden="true">›</span>
 <span>{{ page.title }}</span> 
{%- else -%} 
 <span aria-hidden="true">›</span>
 <span>{{ page_title }}</span> 
{% endif %}
</nav>
{%- endunless -%}

Hey @artofadornment ,

You can modify the breadcrumb logic to prioritize a specific collection instead of defaulting to an alphabetical order.

{%- assign preferred_collections = "necklaces,jewelry,featured" | split: "," -%}
{%- assign chosen_collection = product.collections.first -%}

{%- for preferred in preferred_collections -%}
  {%- assign matched_collection = product.collections | where: "handle", preferred | first -%}
  {%- if matched_collection -%}
    {%- assign chosen_collection = matched_collection -%}
    {%- break -%}
  {%- endif -%}
{%- endfor -%}

This ensures the breadcrumb always prioritizes the right collection. Let me know if you need any tweaks!
If I was able to help you, please don’t forget to Like and mark it as the Solution!
Best Regard,
Rajat

Hi @artofadornment ,

There will be 2 options for you in this case:

  • Option 1: Use session storage to save the collection and display it, this will help you when you go to the collection page before going to the product page, it will display the previous link.

  • Option 2: Create a metafield to store the only collection you want to display at breadcrumbs, then go to products, select the collection and change the code so it displays.

I hope it helps!

Thank you! I tried but, please forgive me, I’m not sure where to paste that in the snippet. If I place it at the beginning and don’t edit anything else, I get two lines of breadcrumbs displaying on the product page, one above the other. Is there a certain area of code I should be replacing with it? I included all of the existing snippet code in my original post… is there a way you could integrate what you’ve written into the section where it should go, so I can copy and replace? I hate to ask, but like I said, my knowledge of coding is OK but somewhat limited. :heart: