I’ve set up a flow workflow to automatically tag products that are newly created or products that have been made back in stock. This tag is then removed after 30 days.
I then have a ‘Recently Added’ collection which contains products with the tag.
My issues now is Shopify only sorts products by newest to oldest, rather than a recently updated. It looks like products have a ‘updated_at’ property in the storefront api but not in liquid. Because of this, the products that I’m trying to display from this collection are not in the order I want them to be.
Is there a way around this in theme development?
I came up with a solution but it involved JS.
In my Flow app I have a workflow which listens for new products or products variants made back in stock. I also added a product level metafield (one line text).
Then, the product is tagged with either ‘new’ or ‘restock’. I have a Recently added collections which contains products only tagged with these tags.
Alonside tagging products in the flow, I also update the product metafield with the products ‘updatedAt’ - a DateTime value. This allows me to get this value in the front end via a data-attribute.
Then using JS, I get all the product card elements and sort by the converted date value. If no date value, then push that item to the end of the array.
const slider = document.querySelector('slider-component.updated-at');
const container = slider.querySelector('ul');
const productCards = Array.from(container.querySelectorAll('.grid__item'));
productCards.sort((a, b) => {
const dateA = new Date(a.getAttribute("data-updated-at"));
const dateB = new Date(b.getAttribute("data-updated-at"));
// Check if the dates are valid
const isValidA = !isNaN(dateA.getTime());
const isValidB = !isNaN(dateB.getTime());
// If A is invalid, send it to the end
if (!isValidA && isValidB) return 1;
if (isValidA && !isValidB) return -1;
if (!isValidA && !isValidB) return 0; // Keep relative order if both are invalid
return dateB - dateA; // Sort valid dates descending (most recent first)
});
productCards.forEach(card => container.appendChild(card));
slider.setSlidePosition(0) // Reset to the first slide
Not the most ideal solution but it works.