Better HubSpot Breadcrumbs

The standard way for creating breadcrumb links on your page in HubSpot is to use a menu module with the breadcrumb menu type selected. This requires you to create a menu and select every page you want to include in the breadcrumbs. This can take a whole lot of time, especially if you have a larger website. Don’t have the time for that? No worries, we’ve got a better solution.

The Better Breadcrumbs Approach

Structured URLs

If you are using breadcrumbs, typically this means you have multiple levels of pages which means you should have structured URLs. An example of a properly structured multi-level URL looks like this:

If you don’t have structured URLs, this method won’t work for you. Also, why don’t you have structured URLs?!?! If you do have structured URLs, read on… πŸ‘‡

Breakdown the URLs with HubL

To get your URL path in HubL we will use the {{ request.path }} global variable. This variable grabs everything after your domain name so using the example above we would get: milky-way-galaxy/solar-system/earth

Create the Array

We need to separate each level so we can link to them individually in the breadcrumb’s menu. To do this we’ll use the split filter. This filter creates an array (multiple items) from a string (a single item). Since our URL uses / for each level, we can easily split the single long string into multiple items like so: {{ request.path|split('/') }}

Loop through the Array

Now that we have our array, we need to loop through each item to build our menu. In order to do this we need to save the array as a variable and then use that variable in the for loop. In HubL, that looks like this:

{% set breadcrumbs = request.path|split('/') %} <ol> {% for item in breadcrumbs %} <li>{{ item }}</li> {% endfor %} </ol>
Code language: Twig (twig)

Add Formatting and Links

Next, we’ll want to link to the parent pages, replace dashes with spaces for the text as well as capitalize the text for better readability.

{% set breadcrumbs = request.path|split('/') %} <ol> {% for item in breadcrumbs %} <li> {% unless loop.last %} <a href="/{{ item }}">{{ item|replace('-',' ')|capitalize }}</a> / {% else %} {{ item|replace('-',' ')|capitalize }} {% endunless %} </li> {% endfor %} </ol>
Code language: Twig (twig)

And that’s it!

The Better Breadcrumbs Gotchas and Downsides

The main drawback to this approach is if you don’t have a complete name in your URLs your text might not read very fluently. The other drawback is if you actually need dashes in between the words in your text, you won’t be able to have them. If either of these are issues for you, you should use the regular menu method. Otherwise, go make yourself that extra coffee with all that time you just saved yourself. β˜•οΈβ˜•οΈβ˜•οΈ

Stefen Phelps

I have a passion for developing responsive layouts, accessible UIs, and performant web apps.


Nich says

Thanks for writing a blog post about this solution! I found it very helpful. I discovered one hangup in building these breadcrumbs for a client who requires breadcrumbs greater than 3 levels deep. So I came up with this HubL solution to account for up to 4 breadcrumbs:

{% for item in path_arr %}

{% if loop.last %}
{{ item|replace(“-“, ” “) }}
{% else %}
{% if loop.length > 2 %}
{% if loop.index == 2 %}
{{ item|replace(“-“, ” “) }}
{% elif loop.index == 1 %}
{{ item|replace(“-“, ” “) }}
{% else %}
{{ item|replace(“-“, ” “) }}
{% endif %}
{% else %}
{{ item|replace(“-“, ” “) }}
{% endif %}
{% endif %}
{% endfor %}

But the nested if statements feels a little messy and I’m not sure this is the best way to implement. If the client required any further levels of path separation, I would need to nest some more logic to account for it. Any other ideas on how to loop through the path array if you have to account for paths with more than 3 separators?

trenton says

How do I add this code? I added a custom HubL module to the page, under the header, then it gives me CSS Class, Inline Styling, and Wrapping HTML. Do I put this code in the Wrapping HTML? Do I edit the module source code?

Stefen Phelps says

I recommend you put the code inside a new custom module (in the HTML/HubL section). Then you can use that module wherever you like in your templates or pages.

Chad says

This is a very cool way of doing Breadcrumbs, I would be cognizant of the fact that when you use {{ request.path }} you are breaking server caching for that page some what. BUT this does make breadcrumbs super flexible.

Stefen Phelps says

Good point Chad. Definitely something to consider. I wonder how much performance difference it actually makes on a typical page, I didn’t notice when I implemented this recently but would be interesting to see the difference (hint hint, write a blog post Chad! πŸ˜‰)

Leave a Comment