Schema.org breadcrumbs for Shopify products/collections

Jump to the solution 🏃‍♂️

During lockdown I found myself, like many others, with a lot more time on my hands. One of my many projects last year was creating a Shopify website and customising one of the free themes.

For those of you who don’t know, if you set up a Shopify partners account you do not have to pay for a Shopify subscription. You can create unlimited staging sites that only start costing you once you go live.

Although my Shopify store never manifested itself I did learn some things about Shopify SEO on my journey.

Something I noticed is that I could not find valid, up-to-date, schema.org breadcrumbs for both collections and products. So with my rudimentary (and I mean really rudimentary) knowledge of liquid I tasked myself with writing my own code.

Why you should use schema.org breadcrumbs

The answer to this is fairly simple – breadcrumbs are great for both search engines and users. They help search engines understand the hierarchy of your site – creating a contextual map between products and their respective collections.

Breadcrumbs help users navigate your site – if they find themselves on a product and want to return to the main collection then there’s a handy hyperlink to do just that.

How Shopify breadcrumbs work

Shopify breadcrumbs work by extracting the collection and product name from the URL. Because a user may find a product through a number of different collections (if your products are inside multiple collections) it makes more sense to dynamically generate breadcrumbs on a user-by-user basis.

Note: this code doesn’t work if you have flattened your Shopify URL structure. By this I mean you have actively changed the code on your homepage and collection pages to remove /collections from product URLs in internal links. So links to your products all look like this:

/product/widget-1

Instead of this:

/collections/widets/widget-1

Although these longer URLs are technically taken care of through the sitemap and use of canonical tags, some SEOs consider the natural structure of Shopify’s URLs to be extremely bloated, which can cause some crawl budget issues on larger sites.

Why you shouldn’t use an app

There’s really no need to pay for an app for such a simple change. You can make this quick edit to your store in less than 10 minutes. This change also means you won’t have to pay any excessive app subscription fees and your site won’t be bloated down with any sloppy or unnecessary code.

Adding the code

This code should be added to your products pages and collection pages wherever you want the breadcrumbs to appear (ideally at the top left of the page).

  1. From your Shopify admin, go to Online Store > Themes.
  1. Click Actions > Edit code.

The code

<!-- /snippets/breadcrumb.liquid -->
{% comment %}
  Documentation - https://shopify.dev/tutorials/customize-theme-add-breadcrumbs
  Rich snippets - https://developers.google.com/search/docs/data-types/breadcrumb
{% endcomment %}
{% unless template == 'index' or template == 'cart' or template == 'list-collections' %}
<ol class="breadcrumb" role="navigation" aria-label="breadcrumbs" itemscope itemtype="https://schema.org/BreadcrumbList">
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ shop.url }}" itemprop="item">
      <span itemprop="name">Home</span>
        <meta itemprop="position" content="1"/>
    </a>
  {% if template contains 'product' %}
  {% if collection %}
  &rsaquo;
  {% if collection.handle %}
  {% capture url %}/collections/{{ collection.handle }}{% endcapture %}
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ url }}" itemprop="item">
      <span itemprop="name">{{ collection.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% endif %}
  {% endif %}
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ product.url }}" itemprop="item">
      <span itemprop="name">{{ product.title }}</span>
      <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% elsif template contains 'collection' and collection.handle %}
  &rsaquo;
  {% if current_tags %}
  {% capture url %}/collections/{{ collection.handle }}{% endcapture %}
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ url }}" itemprop="item">
      <span itemprop="title">{{ collection.title }}</span>
        <meta itempop="position" content="2">
    </a>
  </li>
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ page.url }}" itemprop="item">
      <span itemprop="name">{{ current_tags | join: " + "  }}</span>
        <meta itempop="position" content="2">
    </a>
  </li>
  {% else %}
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ collection.url }}" itemprop="item">
      <span itemprop="name">{{ collection.title  }}</span>
        <meta itemprop="position" content="2" />
    </a>
  </li>
  {% endif %}
  {% elsif template == 'blog' %}
  &rsaquo;
  {% if current_tags %}
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ blog.url }}" itemprop="item">
      <span itemprop="name">{{ blog.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ page.url }}" itemprop="item">
      <span itemprop="name">{{ current_tags | join: " + " }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% else %}
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ blog.url }}" itemprop="item">
      <span itemprop="name">{{ blog.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% endif %}
  {% elsif template == 'article' %}
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ blog.url }}" itemprop="item">
      <span itemprop="name">{{ blog.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ article.url }}" itemprop="item">
      <span itemprop="name">{{ article.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% elsif template contains 'page' %}
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ page.url }}" itemprop="item">
      <span itemprop="name">{{ page.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% else %}
  &rsaquo;
  <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
    <a href="{{ page.url }}" itemprop="item">
      <span itemprop="ame">{{ page.title }}</span>
        <meta itemprop="position" content="2"/>
    </a>
  </li>
  {% endif %}
</ol>
{% endunless %}

You can also find this code with highlighted syntax on my Github: https://github.com/sampennycodes/shopifybreadcrumbs/blob/master/breadcrumbs.liquid

About the author

Sam Penny is an SEO specialist from Australia. He's interested in the ways that we can use SEO, and search data, to improve the user journey.

Leave a comment