Rating Reviews

Commerce

Star rating breakdown with review count.

Preview

4.3
256 reviews
5
150
4
60
3
25
2
12
1
9

Usage

example.jsx
import { RatingReviews } from "@/components/ui/rating-reviews";

export default function Example() {
  return <RatingReviews />;
}

Source Code

Copy this file into components/ui/rating-reviews.jsx in your project.

rating-reviews.jsx
"use client";

import { forwardRef, useState } from "react";
import { cn } from "@/lib/utils";

const RatingReviews = forwardRef(({ className, rating = 0, totalReviews = 0, breakdown = [], ...props }, ref) => (
  <div ref={ref} className={cn("space-y-4", className)} {...props}>
    <div className="flex items-center gap-4">
      <div className="text-center">
        <div className="text-4xl font-bold">{rating.toFixed(1)}</div>
        <div className="mt-1 flex gap-0.5">
          {[1, 2, 3, 4, 5].map((s) => (
            <svg key={s} className={cn("h-4 w-4", s <= Math.round(rating) ? "fill-yellow-400 text-yellow-400" : "fill-muted text-muted")} viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" /></svg>
          ))}
        </div>
        <div className="text-xs text-muted-foreground">{totalReviews} reviews</div>
      </div>
      {breakdown.length > 0 && (
        <div className="flex-1 space-y-1">
          {breakdown.map((b, i) => (
            <div key={i} className="flex items-center gap-2 text-xs">
              <span className="w-4 text-right">{5 - i}</span>
              <div className="h-2 flex-1 overflow-hidden rounded-full bg-muted">
                <div className="h-full rounded-full bg-yellow-400" style={{ width: `${(b / totalReviews) * 100}%` }} />
              </div>
              <span className="w-8 text-muted-foreground">{b}</span>
            </div>
          ))}
        </div>
      )}
    </div>
  </div>
));
RatingReviews.displayName = "RatingReviews";

export { RatingReviews };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge