Splitting Large Collections Across Pages
Shopify limits how many items you can efficiently loop per request. The {% paginate %} tag wraps a for loop and splits results into pages. Shopify provides a paginate object with current page, page size, and total pages.
12 products per page with navigation
{% paginate collection.products by 12 %}
<div class="collection-grid">
{% for product in collection.products %}
{% render 'product-card', product: product %}
{% endfor %}
</div>
{% if paginate.pages > 1 %}
<nav class="pagination" aria-label="Pagination">
{{ paginate | default_pagination }}
</nav>
{% endif %}
{% endpaginate %}The by 12 parameter sets page size. collection.products inside the paginate block only contains the current page's products — not the entire catalog. Use collection.all_products_count for total count display outside the loop.
- paginate.current_page — active page number
- paginate.pages — total page count
- paginate.next.url / paginate.previous.url — navigation links
- default_pagination filter — renders Previous/Next and page numbers
Tip: For AJAX 'Load more' UX, use the Section Rendering API or fetch ?page=2 URLs — paginate is the server-side foundation.