← Projects/Product cards

Build review stars on Shopify collection product cards

A build-along for adding star ratings to the product cards in a Shopify collection grid, read from the reviews.rating metafield, with the review count, accessibility, and a guard for products with no reviews.

Intermediate20 minutes4 stepsFree, no signup

Here's what you'll build

  • Star ratings on every product card in a collection grid
  • The rating read from the reviews.rating metafield a review app maintains
  • A review count and a screen-reader label
  • A guard so newly listed products with no reviews show nothing

Before you start

  • Comfortable looping collection.products on a card
  • Have read a product metafield before

Star ratings on the collection grid are pure social proof, and they're a small amount of Liquid once you know where the rating lives. Here's the finished feature: two products show their stars and review count, and the newly listed decaf (no reviews yet) shows nothing.

northwindcoffee.myshopify.com
The finished feature: stars on rated products, nothing on the unreviewed one.

The theme reads reviews, it doesn't store them

A review app (Judge.me, Loox, Yotpo, Shopify Product Reviews) owns the reviews and writes an aggregate to the reviews.rating and reviews.rating_count metafields. You read those. Never build review storage in the theme.

Step 1

Read the rating and draw the stars

Inside your card loop, round the rating value and loop one to five, printing a filled star when the index is within the rating:

snippets/card-product.liquid
<span class="rating-stars">  {% assign rounded = product.metafields.reviews.rating.value | round %}  {% for i in (1..5) %}    {% if i <= rounded %}{% else %}<span class="star--empty"></span>{% endif %}  {% endfor %}</span>

Step 2

Add the count and an accessible label

liquid
<span class="rating-stars" role="img"      aria-label="Rated {{ product.metafields.reviews.rating.value }} out of 5">  {% assign rounded = product.metafields.reviews.rating.value | round %}  {% for i in (1..5) %}{% if i <= rounded %}{% else %}<span class="star--empty"></span>{% endif %}{% endfor %}</span><span class="rating-count">({{ product.metafields.reviews.rating_count }})</span>

Step 3

Hide it for products with no reviews

liquid
{% if product.metafields.reviews.rating_count > 0 %}  {% comment %} ...the stars + count from above... {% endcomment %}{% endif %}

Tip

There's an interactive version where you write each step yourself and watch the stars appear on a real collection. Build it in the editor →

Learn this properly

This project shows you the working code. To actually internalize the patterns behind it (so you can build the next feature without copying), take the matching lessons in the platform. Free during the beta.

  • Lesson

    Review stars on the product card

    You can render review stars on a collection product card by reading the `reviews.rating` and `reviews.rating_count` metafields a review app maintains, drawing the stars in Liquid, and hiding the block for products with no reviews.

  • Lesson

    Read your metafield: roast date on the PDP

    You can read a defined metafield in Liquid via `product.metafields.<namespace>.<key>`, and you understand that the value is `nil` until the merchant fills it in admin.

  • Lesson

    Build the collection page layout

    You can build a collection template that reads the collection's own metadata (`title`, `products_count`, `description`) for the header, loops `collection.products` into a grid of cards with product images, and links each card to its product page.

FAQ

Where do Shopify review stars come from?

A review app writes the aggregate rating to metafields, conventionally reviews.rating (a rating type) and reviews.rating_count. The theme reads product.metafields.reviews.rating.value and reviews.rating_count and draws the stars.

How do I add review stars without an app's own snippet?

Loop {% for i in (1..5) %} over the rounded rating value and print a filled or empty star. Add the count from reviews.rating_count and guard the block with {% if reviews.rating_count > 0 %}.

Found a bug, a better pattern, or want to suggest the next project? Email hello@learnshopify.dev.