Skip to content

Collection

The collection page. A masthead, a toolbar carrying filter / result count / sort, a row of active-filter chips, then the product grid and its pagination.

SettingTypeDefaultWhat it does
EyebrowTextThe indexSmall accent line above the collection title
Show the collection descriptionCheckboxtrueShow the collection description beside the title
Show the collection imageCheckboxfalseShow the collection image as a small plate in the masthead
Show the result countCheckboxtrueShow the result count in the toolbar
SettingTypeDefaultWhat it does
ColumnsRange 2–64Columns on desktop
Products per pageRange 8–48, step 424Products per page
Show a short description on each cardCheckboxfalseShow a short description on each card
SettingTypeDefaultWhat it does
Enable filteringCheckboxtrueShow the filter button and drawer. Which filters exist is managed in Shopify’s Search & Discovery app
Filter button labelTextFilterThe filter button’s label
Enable sortingCheckboxtrueShow the sort dropdown
SettingTypeDefaultWhat it does
Empty headingTextNothing here yetHeading when the collection itself is empty
Empty button labelTextShop everythingButton under that heading, linking to all products
No filter matchesTextNothing matchesHeading when filters have excluded everything. Its button clears the filters instead
PaginationSelectbuttonpages (numbered) · button (load more) · infinite (auto-load)

The description only renders when show_description is on and the collection actually has one; it is stripped of HTML and truncated to 160 characters. Without a description the masthead goes solo — the title stretches across rather than leaving a stranded empty column.

The result count lives in the toolbar, beside filter and sort, where a shopper looks for it and where show_count governs it.

Filters come from Shopify’s Search & Discovery app; the theme renders whatever that app publishes. Signal reads collection.filters and does not define any filters of its own.

Shared with the search page. A left-hand dialog with one <details> group per filter, open by default, each showing a count of its active values.

  • List filters (tags, options, vendor, product type, availability) render as checkboxes with their result counts. A value with a count of zero that is not currently active is disabled and dimmed, so a shopper cannot filter their way to nothing.
  • Price range filters render as two number inputs, pre-filled from the active range and placeholdered with the collection’s own bounds.

Behaviour:

  • Ticking a checkbox submits immediately — no apply step needed. The Apply button is still there for the price inputs and for keyboard users.
  • Empty number inputs are disabled on submit, so an untouched price field never adds a blank filter.v.price.gte= to the URL.
  • The current sort and (on search) the query are carried as hidden inputs, so filtering never silently resets them.
  • Opening locks page scroll, moves focus to the close button, and returns focus to the filter button on close. Escape and the backdrop both close it.

Above the grid, every active value renders as a removable chip linking to its own url_to_remove, followed by a Clear all link back to the bare collection.

A price range gets one chip stating both ends — a chip reading only “Price” says nothing about what was filtered. An end the shopper left unset falls back to the filter’s own bound.

A native <select> of collection.sort_options. Changing it sets sort_by in the URL and drops page, so you always land on page one of the new order.

Signal layers load-more over real pagination rather than replacing it. The numbered pager is always in the markup and always works; the script hides it and takes over when a button or infinite scroll is chosen.

PaginationWhat the shopper sees
Numbered pagesThe numbered pager only
Load more buttonA Load more button plus a live “showing n of total” line
Infinite scrollThe same thing, loading on its own as the shopper nears the end
  1. The button fetches the next page’s URL and appends the cards it finds inside [data-col-grid].

  2. Newly injected cards are handed to the reveal observer and the wishlist painter, so their animations and saved-state hearts work like the cards that were there at load.

  3. The “showing n of total” line and the next-page URL are read off the fetched page, so the count stays honest.

  4. When there is no next page, the button hides itself.

When Theme settings → Quick view & wishlist → Enable product comparison is on, every product card carries a compare control, and the layout renders a persistent tray plus a comparison dialog.

  • Up to 4 products, held by the shopper’s own browser, so the selection survives navigating between collections and products.
  • The tray is hidden until something is picked, and carries a count, a Clear control and a per-item remove button.
  • Opening the dialog fetches /products/<handle>.js for each pick and builds the matrix client-side.
  • Rows are drawn from what Shopify actually knows: price, availability, type, vendor, and the products’ options. A row is only drawn when at least one of the compared products has a value for it, so an option nobody shares never becomes an empty band of dashes.
  • Trying to add a fifth shows a toast rather than silently dropping one.

Cards are rendered by the shared prod-card snippet, so the collection grid, search results, the wishlist page and every recommendation row look identical and inherit the same badges, hover image swap, quick view, wishlist heart and compare control. show_blurbs is passed through to add a short line to each card.

The grid is laid out with a --cols custom property, and cards stagger in as they enter the viewport (honouring reduced motion and the global motion setting).