So you've been tweaking your Shopify, everything's looking great... and then you realise
customers have no idea where they are.
That's where breadcrumbs come in.
Not the edible kind unfortunately - the navigation kind.
They look a little something like this:
Home > Collection > Product
They help users navigate your store easily, improve the overall user experience and give your
SEO a small boost. Little win all round.
Let's walk through how to add them to your Shopify store - no advanced skills required.
To have this work effectively you need collections set up. If you don't already have
collections, you can learn how to do this here --
Step 1: Duplicate Your Theme (Seriously)
Before touching any code, back up your theme, you do not want to lose anything you've spent
time working on.
Go to:
Online Store > Themes > ... > Duplicate
If something breaks, you'll thank yourself later.

Step 2: Open Your Theme Code
Head over to:
Online Store > Themes > Edit Code
Welcome to the engine room.
Step 3: Create the Breadcrumb File
In the code editor:
1. Open the Sections folder
2. Click Add a new file
3. Name it breadcrumb.liquid
Step 4: Add the Breadcrumb Code
Copy and paste the breadcrumb code (found at the bottom of this post) into the file you have
just created and be sure to save it.
Step 5: Adding the Breadcrumbs to Your Storefront
Now head back to:
Online Store > Themes > Edit Theme
Inside the theme editor:
Within the Header section, click Add Section and select your new Breadcrumb Navigation section.
Once added, your Breadcrumbs should look something like this:
Customising the Breadcrumbs
At this point, you can tweak the fonts, colours and sizes so everything matches the rest of
your store.
A little styling goes a long way.
Final Thoughts
Breadcrumbs are one of those small changes that makes your store feel way more polished.
Benefits include:
- Better navigation
- Cleaner user experience
- Small SEO improvements
- Happy customers that don't get lost
And the best part?
You can add them in under 20 minutes.
If your Shopify store doesn't already have breadcrumbs, this is one of the easiest improvements
you can make.
BREADCRUMB CODE:
{%- style -%
} :root {
--svg_fill: {{ section.settings.breadcrumb_text_color}}
;
}
.home-icon-container {
display: inline-block;
margin-right: 4px;
vertical-align: sub;
}
.breadcrumbs {
padding: 1rem 2rem;
color: {{ section.settings.breadcrumb_text_color }}
;
background-color: {{ section.settings.breadcrumb_bg_color }}
}
.breadcrumbs li {
display: inline-block;
}
.breadcrumbs a {
text-decoration: none;
/*Will put liquid customization here*/
font-size: 15px;
color: inherit;
}
{%- if section.settings.breadcrumb_accent_color_bool -%}
.breadcrumbs a:last-of-type {
color: {{ section.settings.breadcrumb_accent_color }}
!important;
}
{%- endif -%}
.breadcrumb-delimeter:not(:last-child):after {
{%- case section.settings.breadcrumb_delimeter -%}
{%- when "angle_right" -%}
content: "›";
font-size: 18px;
{%- when "slash" -%}
content: "/";
font-size: 16px;
{%- when "arrow_right" -%}
content: "➤";
font-size: 15px;
{%- when "squiggle_arrow" -%}
content: "\27FF";
font-size: 25px;
{%- when "right_long" -%}
content: "\279E";
font-size: 18px;
transform: translateY(5%);
{%- when "double_right" -%}
content: "\00BB";
font-size: 20px;
{%- when "diamond_arrow_head" -%}
content: "⤞";
font-size: 25px;
transform: translateY(5%);
{%- when "heavy_angle_right" -%}
content: "\276F";
font-size: 18px;
transform: translateY(5%);
{%- else -%}
{%- endcase -%}
display: inline-block;
margin-left: 0.75rem;
margin-right: 0.50rem;
speak: none;
}
.breadcrumbs [aria-current="page"] {
color: inherit;
font-weight: normal;
text-decoration: none;
}
{%- endstyle -%}
<div class="breadcrumbs" aria-label="breadcrumbs">
{%- unless template == 'index' or template == 'cart' -%}
{%- if section.settings.breadcrumbs_home_icon_bool -%}
<div class="home-icon-container">
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
class="bi bi-house-door-fill"
viewBox="0 0 16 16">
<path d="M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z" />
</svg>
</div>
{%- endif -%}
<a href="/" title="Home">Home</a>
{%- case template.name -%}
{%- when 'article' -%}
{%- for link in linklists.main-menu.links -%}
{%- if link.url == blog.url -%}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<!--Breadcrumb Delimeter -->
{{ link.title | link_to: link.url }}
{% break %}
{%- endif -%}
{%- endfor -%}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<a href="{{ article.url }}" aria-current="page">{{ article.title }}</a>
{%- when "product" -%}
{%- capture product_url_string -%}
{%- for collection in product.collections -%}
{{ collection.url }}|
{%- endfor -%}
{%- endcapture -%}
{%- assign object_url_string = product_url_string | append: product.url -%}
{%- 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: gclink_handle | append: '|' -%}
{%- assign link_handles = link_handles | append: gclink_handle | append: '|' -%}
{%- 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 -%}
{%- comment -%} CONVERT TO ARRAYS {%- endcomment -%}
{%- 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 = '' %}
{%- 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 class="breadcrumb-delimeter" aria-hidden="true"></span>
<!--Breadcrumb Delimeter -->
{{ bc1 }}
{%- endif -%}
{%- if bc2 -%}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
{{ bc2 }}
{%- endif -%}
{%- if bc3 -%}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
{{ bc3 }}
{%- endif -%}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<a href="{{ product.url }}">{{ product.title }}</a>
{%- else -%}
{% for link in linklists.main-menu.links %}
{% if link.child_active or link.active %}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<!--Breadcrumb delimeter-->
<a href="{{ link.url }}">
{{ link.title | escape }}
</a>
{% for clink in link.links %}
{% if clink.child_active or clink.active %}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<a href="{{ clink.url }}">
{{ clink.title | escape }}
</a>
{% for gclink in clink.links %}
{% if gclink.child_active or gclink.active %}
<span class="breadcrumb-delimeter" aria-hidden="true"></span>
<a href="{{ gclink.url }}">
{{ gclink.title | escape }}
</a>
{% endif %}
{%- endfor -%}
{% endif %}
{%- endfor -%}
{% endif %}
{%- endfor -%}
{%- endcase -%}
{%- endunless -%}
</div>
<script defer>
const breadCrumbLinks = document.querySelectorAll(".breadcrumbs a")
const lastLink = breadCrumbLinks[breadCrumbLinks.length - 1]
lastLink.href = "javascript:void(0)"</script>
{% schema %}
{
"name": "Breadcrumb Navigation",
"settings": [
{
"type": "header",
"content": "Icon Settings"
},
{
"type": "checkbox",
"id": "breadcrumbs_home_icon_bool",
"label": "Use the home icon next to the Home link in the breadcrumb",
"default": true
},
{
"type": "select",
"id": "breadcrumb_delimeter",
"info": "The icon that is between every link in the breadcrumb",
"label": "Breadcrumb Delimeter Icon",
"options": [
{
"value": "angle_right",
"label": "Angle Right"
},
{
"value": "slash",
"label": "Slash"
},
{
"value": "arrow_right",
"label": "Arrow Right"
},
{
"value": "squiggle_arrow",
"label": "Squiggle Arrow"
}, {
"value": "right_long",
"label": "Right Long"
}, {
"value": "double_right",
"label": "Double Right"
}, {
"value": "diamond_arrow_head",
"label": "Diamond Arrow Head"
}, {
"value": "heavy_angle_right",
"label": "Heavy Angle Right"
}
],
"default": "angle_right"
},
{
"type": "header",
"content": "Color Settings"
}, {
"type": "color_background",
"id": "breadcrumb_bg_color",
"label": "Breadcrumb Background Color",
"info": "Change the Background Color of the breadcrumb. Be sure to pick something that will have a nice color contrast from the color of the text",
"default": "#fff"
}, {
"type": "color",
"id": "breadcrumb_text_color",
"label": "Breadcrumb Color",
"default": "#465076"
}, {
"type": "checkbox",
"id": "breadcrumb_accent_color_bool",
"label": "Enable accent color for last link in breadcrumb",
"info": "By checking this checkbox, you are adding an accent color to the last link in your breadcrumb navigaiton.",
"default": false
}, {
"type": "color",
"id": "breadcrumb_accent_color",
"label": "Current Page Accent Color",
"default": "#4770db"
}
],
"presets": [
{
"name": "Breadcrumb Navigation"
}
]
}
{% endschema %}
Post a Comment