{% paginate collections.collectionname.products by 1000 %}
{% for product in collections.collectionname.products %}
{{ forloop.index }}
{% endfor %}
{% endpaginate %}
However, even though I’m paginating by 1000, only 250 products are actually being iterated over — I verified this using {{ forloop.index }} for debugging.
I need to be able to loop through all products in the collection to show users all relevant results.
Is there any workaround or trick to access the entire collection, maybe by looping through all pages or using another approach?
There is a limit on pagination size. Initially it was 50, then it was changed to the higher value, but there is a reason for the limit – performance, both from on the storefront and server side.
Looping over all collection products, especially when there are more than 250 of them will take quite some time and delay rendering your page.
There was always an option to use {% layout none %} and fetch this data with Ajax – in this case maximum pagination size was significantly higher.
Have you considered other approaches – not sure what your goal is, but maybe using search and filtering can help here?
Reviving this thread as original author did not mention this important part – with recent increase in possible pagination size to 250, was it also made the same limit for {% layout none %} templates instead of previous 1000?
If yes, it’d be good to mention this in documentation.
Because for me now this is reset to 250
{%- layout none -%}
{%- paginate collection.products by 1000 -%}
Hey @tim_tairli - thanks for following up, I’ll double check on this for you and loop back once I can confirm this. Speak with you as soon as I have that info on my end here.
Hi @tim_tairli following up here with some info - I was able to speak with one of our theme product developers and can confirm that we’ve standardized pagination across Liquid (including templates that use {% layout none %}) and AJAX.
The cap is now 250 items per page. The old 1000-item behavior wasn’t a supported guarantee and was changed for consistency and performance. I was able to confirm it is expected behaviour at the moment, but if you’re open to sharing your use case for the higher limit, I’m more than happy to get back in touch with folks internally and see if we can offer a workaround or at the very least log a formal feature request for you. Just ping me here and let me know, happy to help where I can.
It’s just I’ve stumbled upon the several years old solution where they fetch entire product inventory of the store and keep the data locally.
The code stopped working because they were paginating by 1000 and calculated number of fetches as {{ shop.products_count | divided_by: 1000.00 | ceil }}
I personally understand the optimisation and standardisation reasons and can work around this limitation myself.
It’d be the best if you can mention it in documentation somewhere that {% layout none %} has the same limit since there are a lot of people who remember otherwise (even though it was not a “supported guarantee”).
Just in case – before writing my answer above i’ve checked the dox – nothing.
Hey again @tim_tairli, really appreciate the follow-up and for checking the docs. You’re correct: the 250 cap applies across Liquid, including templates using {%- layout none -%}. I’m going to go ahead and submit a request to update the docs to explicitly call this out so it’s clearer for folks who remember the old behavior and I’ll circle back here once I have more info on that for you as well (can’t guarantee anything, but I’ll do my best to advocate).
For cases where you need a full product catalog export to keep a local copy in sync, my recommendation would be using the Admin GraphQL Bulk Operations API together with product/inventory webhooks. That flow is designed for large catalogs and avoids storefront pagination limits, but I definitely understand the need to retrieve this info from the storefront directly in some cases. If you have constraints that make Bulk Ops impractical though, let me know and I can pass that context along as well!
@Alan_G If the pagination limit is now 250, why is the for loop limit / array filters still capped at 50? There are a ton of use cases (metaobject data, mapping product attributes, etc.) where 50 is way too low and 250 is more reasonable. We keep having to reach for the Storefront API within Liquid themes to address the shortcoming, however there are drawbacks to using it, particularly when B2B / customer context is required. This continues to be a pain point for development.
Hey @Nic_Oliver , thanks for flagging, just confirming, are you referencing something like this when it comes to the loop limit/array filter?
{% paginate collection.products by 250 %}
{% for product in collection.products %}
{% endfor %}
Just wanted to confirm exactly what you’re seeing. My understanding is that this is currently expected behaviour, but I’m happy to do some more digging into this internally for you to see if we can share why that is/log a feature request for you at the very least.
On a collection page, you can access up to 250 entries from that collection, if the paginate tag is used on that template. For example on collections/bikes, all of these lists will print up to 250 results:
{%- paginate collection.products by 250 -%}
<ol>
{%- for product in collection.products -%}
<li>{{ product.id }}</li>
{%- endfor -%}
</ol>
{%- endpaginate -%}
<ol>
{% for product in collection.products %}
<li>{{ product.id }}</li>
{% endfor %}
</ol>
{% assign ids = collection.products | map: 'id' %}
<ol>
{% for id in ids %}
<li>{{ id }}</li>
{% endfor %}
</ol>
However, if the first liquid block with the paginate tag is removed, the subsequent loops will only print 50 entries. This isn’t well documented and is confusing unless you actually take the time to test different scenarios.
In addition, looping through other types of arrays on different page types is still limited to 50 entries. It’s common to need access to more than 50 entries, especially with metaobjects.
For example, say you have a section setting that is type: collection - if you want to loop the products from that collection, you are still limited to 50. The same is true for metaobjects.
With the Storefront API, there are not different limits based on what page type you are on - you can get 250 of any resource. The same should be true in Liquid if trying to match the Storefront API
Thanks for following up @Nic_Oliver and for clarifying, really appreciate it. I can’t guarantee anything on my end, but I’ll speak with some folks internally and see if this is on the roadmap. Like I mentioned there, happy to log a feature request at the very least. I’ll loop back with you once I have more info to share.
Does this mean, a collection can’t have more than 5 pages anymore? (50*5). For sure this limit was not guaranteed, but many of us used it still because it’s too little in certain scenarios.
I have the case for a client that sells nail designs, they have over 300+ designs. Even with pagination or lazyloading, I’m no longer able to display all designs in the collection without using some new tricks (which should not have to be).
The 50 limitation loop is already low enough as it is, but the total limitation of 250 feels like a step back. Shopify wants to introduce 2000+ variants because 100 isn’t enough, and at the same time you lower the collection pagination limit from 1000 to 250. Might be different, but it’s just more problem and less solution as far as I’m concerned.
Thanks for flagging this @tim_tairli - I’ll speak with some folks internally on this to confirm if this is expected behaviour and loop back with you all here when I can confirm that/if we need to update the docs as you mentioned there!
Hey again @tim_tairli and all. Just looping back here to confirm that we’re looking into this more widely now after a bit of testing on our end. Still can’t confirm an exact turnaround time or what next steps will look like, but it is odd that we’re returning that error. I’ll keep you updated and get back in touch here once I have more info.
Apologies for all the pings, but I have some confirmation on this @tim_tairli ! I can confirm that all_products is not expected to paginate, so the error you’re seeing there is expected behaviour. We’ll be updating our docs to fix this, appreciate you mentioning this, just wanted to thank you again
@Alan_G also, if people are looking at pagination issues – if collection object is coming from section settings, pagination does not work for its products.
Same for blog and articles:
Basically, if i have a collection setting in my section, {% paginate section.settings.collection.products by 100 %} is ignored and only up to 50 products are given.
There is a workaround though – to fetch collection via collections
{% assign co = collections[section.settings.collection.handle] %}
{% paginate co.products by section.settings.products_to_show %}
{%- for product in co.products limit: section.settings.products_to_show -%}
If collection object comes from metafields, then its products are paginated properly.