Nested Collections in Shopify Part 2
In this part of the article we will go over step by step of how to make nested collections

Picking up from part 1

Part 1 of this article gave a brief overview of how to create a simple version of nested collections, but it doesn't have all the features most users need for navigating the site.

This part is why I'm writing this article. We had a Shopify project that had a very large product catalogue with multiple different departments each with many categories inside. We had to come up with a way to carry this multi-department/category structure over to Shopify to keep the consistency of the brick and mortar store while making it easy and intuitive for users to find what they're looking for. The method ended up being fairly straightforward but it took some time to wrap our heads around what would be the best way for things to be manageable in the future and able to grow with the catalogue.

In this part of the article we will go over step by step of how to make nested collections as seen in this short screencap.

Content management is UX

One suggestion I'd like to make is on product organization. The method described in this article can be used to nest collections infinitely deep, depending on how much time you want to spend on configuration. I think it is important to think about the user first in every content or design decision made, especially when that decisions changes the way people give YOU money. It is always important to give users the most simple path to finding what they're looking for, sometimes less is more in this situation. You don't want the user to have to sift through every little filter possible before they're able to see products. Some users may want to just browse your products with only a rough idea of what they're interested in. You don't want to put up barriers that slow down or confuse people, just because the way your products are organized makes sense to you doesn't mean it will make sense to someone seeing it for the first time. I wouldn't recommend nesting collections deeper than three levels, to me anything more would be a sign of a barrier for the users.

High level navigation

Just like before we need to create a new navigation menu, this will be an even higher level than before. We can think of it as sort of a department menu, it will group together the most general "departments" of products. The links in the department menu will be to the collections; "Wheels and Tires", "Bikes", and "Accessories", for this example these are the three "departments" we have in our store.

Here's an overview of what the "Department Menu" might look like. As you can see it looks a lot like a drop down menu, that's because we're using the exact same technique in basically the same way. We'll only be focusing on one branch of the hierarchy tree but as you can see each branch has the same structure and the steps can be repeated for each one.

- department-menu
-- Wheels and Tires
--- Wheels
---- Pure Fix Wheels
--- Tires
---- Continental Tires
---- Kenda Tires
---- Thickslick Tires
--- Tubes
-- Bikes
--- Road
--- Mountain
--- BMX
-- Accessories
--- Helmets
--- Bells
--- Lights

This menu could even be what you use in the header of your website as the main navigation for users.

Connecting the navigation

Make a snippet called breadcrumb-menu.liquid and assign some global variables:

{%- assign second_level_filter_list = '' -%} {%- assign third_level_filter_list = '' -%} {%- assign fourth_level_filter_list = '' -%}

We need to find each parent level of menu lists for the current collection. We know the first level menu list is always "department-menu" so that's where we start.

Loop through each link in the department menu, and check if that link is active. If that link is active then that means the user is currently in that collection. Save the handle of that link as the second_level variable we declared earlier and then `{%- break -%}` to stop looping since we found the position of the user.

{%- for first_level_link in linklists['department-menu'].links -%} {%- assign second_level_list_handle = first_level_link.title | handleize -%} {%- if first_level_link.active -%} {%- assign second_level_filter_list = second_level_list_handle -%} {%- break -%} {%- endif -%} {%- endfor -%}

Now we repeat the same process for the next level of nesting. For each link in the department-menu we check if there is a menu that belongs to that link. If it does then we loop through each one of those and again look an active link to indicate the location of the user. If an active link is found then we again assign the `second_level_filter_list` and now the `third_level_filter_list` handles, then break like before.

{%- for first_level_link in linklists['department-menu'].links -%} ... {%- if menus[second_level_list_handle].links != blank -%} {%- for second_level_link in menus[second_level_list_handle].links -%} {%- assign third_level_list_handle = second_level_link.title | handleize -%} {%- if second_level_link.active -%} {%- assign second_level_filter_list = second_level_list_handle -%} {%- assign third_level_filter_list = third_level_list_handle -%} {%- break -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- endfor -%}

Then again, do the exact same thing for the next level. You can keep doing this nesting as far as you want, just be sure to keep in mind the potential UX problems of nesting too far.

The final script will look like this:

{%- assign second_level_filter_list = '' -%} {%- assign third_level_filter_list = '' -%} {%- assign fourth_level_filter_list = '' -%} {%- for first_level_link in linklists['department-menu'].links -%} {%- assign second_level_list_handle = first_level_link.title | handleize -%} {%- if first_level_link.active -%} {%- assign second_level_filter_list = second_level_list_handle -%} {%- break -%} {%- endif -%} {%- if menus[second_level_list_handle].links != blank -%} {%- for second_level_link in menus[second_level_list_handle].links -%} {%- assign third_level_list_handle = second_level_link.title | handleize -%} {%- if second_level_link.active -%} {%- assign second_level_filter_list = second_level_list_handle -%} {%- assign third_level_filter_list = third_level_list_handle -%} {%- break -%} {%- endif -%} {%- if menus[third_level_list_handle].links != blank -%} {%- for third_level_link in menus[third_level_list_handle].links -%} {%- assign fourth_level_list_handle = third_level_link.title | handleize -%} {%- if third_level_link.active -%} {%- assign second_level_filter_list = second_level_list_handle -%} {%- assign third_level_filter_list = third_level_list_handle -%} {%- assign fourth_level_filter_list = fourth_level_list_handle -%} {%- break -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- endfor -%} {%- endif -%} {%- endfor -%}

The main logic behind linking the nested collections together is done, all that's left is to display the lists in the template.

Displaying the links

This part completely depends on your theme; where and how you choose to display these navigation menus is up to you. I'll be showing it in its simplest form using the Debut theme. It doesn't look very pretty but it gets the job done.

Start by including the department menu snippet.

{%- include 'department-menu' -%}

To list the first level "department" links you can just print out the links like any other navigation menu in shopify. For each of the global variables we made in the department-menu snippet check if that linklist has links, if it does then print them out. I'm also adding a heading to the links by filtering the handle to replace dashes with spaces and to capitalize the first letter of each word. Learn more about string filters in liquid.

{%- if linklists[second_level_filter_list].links != blank -%} <nav> <h3>{{ second_level_filter_list | replace: '-', ' ' | capitalize }}</h3> <ul> {%- for link in linklists[second_level_filter_list].links -%} <li> <a href="{{ link.url}}">{{ link.title | escape }}</a> </li> {%- endfor -%} </ul> </nav> {%- endif -%}

Then simply do the same for each level of nesting after by replacing `second_level_filter_list` with the next variable.

Now for every collection you visit that is part of the nesting structure you will get navigation menus based on its parent and child collections.

Wrapping up

There are still some optimizations we could make to clean things up, but I'm hoping you're able to modify the code to work for you. This is just meant as a demo to show the main idea. There are many possibilities that have now opened up in our own custom theme development work. Remember to not get caught up in the technical details and forget about the reason you're doing this in the first place, to make the users life easier.