Reviews
Product ratings, customer photos and reviews for a product page. Handles rating filters, helpful votes, review photos and products with no reviews yet.
Reviews is the reviews section of a product page: an average with stars, a rating histogram, feature ratings, a size scale, a strip of customer photos and the review list. It takes an array of reviews and works out the stats itself, or takes stats from your API when you only load a page at a time.
Every histogram bar is a button. Click 4 stars and the list shows only 4-star reviews, the bar stays highlighted, a removable 4 stars chip appears above the list and screen readers hear how many reviews match. Filters are single-choice, combine with With photos, search within reviews and four sort orders, and an empty result offers to clear them. With five reviews or fewer the histogram is hidden, since a distribution of three reviews says nothing.
Each review shows its stars, title, body clamped at six lines with Read more, the buyer’s name with a Verified buyer badge, the variant they bought and their size feedback. Photos open a lightbox. A merchant reply sits indented under the review. Helpful votes count up straight away, one vote per review, and roll back with a message if your API fails. Rating-only and photo-only reviews lay out without empty gaps.
WriteReview is a dialog, a bottom sheet on phones, with a star rating input, title, body with a minimum length, a Runs small · True to size · Runs large scale, photo uploads with previews, name and email. It validates in place, keeps the draft if the shopper closes it, and ends on “Thanks, your review will appear after a quick check.” RatingStars, RatingInput, ReviewsSummary, ReviewPhotos and ReviewList also work on their own.
HextaUI Pro holen
Eine einmalige Zahlung schaltet jeden Block frei, auch künftige. Preise ansehen.
Die Pro-Registry zu components.json hinzufügen
components.json Token hinzufügen
Erstelle auf deiner Kontoseite einen Token und trage ihn in
.env.localalsHEXTAUI_PRO_TOKENein.Den Block hinzufügen
pnpm dlx shadcn@latest add @hextaui-pro/reviews
From Judge.me, Yotpo or Shopify
Map each provider’s review once to the Review shape. Judge.me pictures, Yotpo images and custom fit fields, helpful votes and merchant replies all have a place, and Shopify’s product review metaobjects map in a few lines.
Server-side pagination
For products with thousands of reviews, pass stats from your API and set manual. Rating, photo, search and sort changes come out through onQueryChange, Show more calls onLoadMore, and the list dims while the next page loads.
Submit with photos
WriteReview hands you the rating, text, fit, photo Files, name and email. Post them as FormData. Throw an Error with a specific message and it shows in the dialog while everything the shopper wrote stays put.
Aufbau
Die Teile, die du zusammensetzt, von außen nach innen.
| Part | Beschreibung |
|---|---|
Reviews | The whole section: summary on the left, photos and list on the right, stacked on narrow screens. |
ReviewsSummary | Average, stars, review count, histogram filter, feature ratings, size scale and Write a review. |
ReviewPhotos | A scrolling strip of every customer photo, opening a lightbox that links back to the review. |
ReviewList | Toolbar, filter status, review items, Show more and empty states. |
WriteReview | The review form in a dialog, with validation, photo uploads and a success state. |
RatingStars, RatingInput | Star display with fractional fill, and a star radio group for writing a review. |
getReviewStats, queryReviews, formatCount | Work out stats, filter and sort reviews, and format counts like 1,284 or 12.4K. |
Reviews
Also takes div props.
| Prop | Typ | Standard |
|---|---|---|
reviewsThe reviews to show. In manual mode, the pages loaded so far. | Review[] | – |
statsCount, average, distribution, feature ratings and fit. Worked out from reviews when left out. | ReviewStats | – |
attributesWhich feature ratings to show, in order, with labels for each end of the scale. | { name: string; low?: string; high?: string }[] | – |
photoReviewsReviews for the photo strip, when they differ from the loaded page. | Review[] | – |
queryThe rating filter, With photos, search and sort. Controlled when set. | ReviewQuery | – |
defaultQueryThe starting query when uncontrolled. | Partial<ReviewQuery> | – |
onQueryChangeCalled when a filter, the search or the sort changes. Search changes are debounced. | (query: ReviewQuery) => void | – |
manualThe reviews are already filtered, sorted and paged by your server. | boolean | false |
totalHow many reviews match the query, in manual mode. | number | – |
hasMoreWhether another page exists, in manual mode. | boolean | – |
onLoadMoreLoads the next page. A rejected promise shows Couldn’t load more reviews with a retry. | () => void | Promise<void> | – |
loadingDims the list while a new query loads. | boolean | – |
pageSizeReviews per Show more step when paging on the client. | number | 5 |
onVoteSaves a helpful vote. Counts change at once and roll back if it throws. null removes the vote. | (review, vote: "up" | "down" | null) => void | Promise<void> | – |
votesVotes the shopper already cast, by review id. | Record<string, "up" | "down"> | – |
onSubmitReviewEnables Write a review. Throw an Error to show its message in the form. | (draft: ReviewDraft) => void | Promise<void> | – |
productShown at the top of the review form. | { title: string; image?: string; variant?: string } | – |
fitShow the size scale in the summary and the form. | boolean | true |
histogramThresholdHide the histogram at this many reviews or fewer. | number | 5 |
merchantNameName used for merchant replies without an author. | string | – |
localeLocale for numbers and dates. | Intl.LocalesArgument | "en-US" |
labelsEvery user-facing string, per part. | { summary?, list?, photos?, write? } | – |
ReviewsSummary
Also takes section props.
| Prop | Typ | Standard |
|---|---|---|
statsThe numbers to show. | ReviewStats | – |
ratingThe active histogram filter. | 1 | 2 | 3 | 4 | 5 | null | – |
onRatingChangeCalled with the clicked rating, or null when the active bar is clicked again. | (rating) => void | – |
onWriteReviewShows the Write a review button. | () => void | – |
headingLevelHeading level for Customer reviews. | 2 | 3 | 2 |
ReviewList
Also takes section props, and the list props of Reviews.
| Prop | Typ | Standard |
|---|---|---|
countTotal reviews for the product, used for the no reviews yet state. | number | – |
onWriteReviewShows Write the first review in the empty state. | () => void | – |
showToolbarShow search, With photos and sort. | boolean | true |
actionsRefreveal clears filters if needed, pages to the review, scrolls to it and focuses it. | Ref<{ reveal(id: string): void }> | – |
ReviewPhotos
Also takes section props.
| Prop | Typ | Standard |
|---|---|---|
reviewsReviews whose photos fill the strip. | Review[] | – |
onJumpToReviewShows Read review in the lightbox. | (review: Review) => void | – |
| Prop | Typ | Standard |
|---|---|---|
openWhether the dialog is open. Controlled when set. | boolean | – |
onOpenChangeCalled when the dialog opens or closes. It can’t close while submitting. | (open: boolean) => void | – |
onSubmitReceives rating, title, body, fit, photos as File[], name and email. | (draft: ReviewDraft) => void | Promise<void> | – |
minBodyLengthMinimum characters when the shopper writes a review body. | number | 20 |
maxPhotosHow many photos can be attached. | number | 5 |
maxPhotoBytesLargest photo accepted, in bytes. | number | 10485760 |
defaultValuesPrefill for signed-in shoppers or a rating picked from an email. | { name?, email?, rating? } | – |
RatingStars
Also takes span props.
| Prop | Typ | Standard |
|---|---|---|
valueA rating from 0 to 5. Fractions fill part of a star. | number | – |
sizeStar size. | "sm" | "default" | "lg" | "default" |
RatingInput
Also takes div props.
| Prop | Typ | Standard |
|---|---|---|
valueThe chosen rating. Controlled when set. | 1 | 2 | 3 | 4 | 5 | null | – |
onValueChangeCalled when a star is chosen. | (value) => void | – |
invalidMarks the group invalid. | boolean | – |
labelsStar names and the Poor to Excellent descriptions. | Partial<RatingInputLabels> | – |
| Prop | Typ | Standard |
|---|---|---|
id, rating, author, createdAtRequired fields. createdAt is an ISO date. | string, number, string, string | – |
title, bodyOptional, so rating-only and photo-only reviews work. | string | – |
verified, variant, fitVerified buyer badge, the variant bought, and runs small, true to size or runs large. | boolean, string, -1 | 0 | 1 | – |
photosCustomer photos. | { id; src; thumbnail?; alt? }[] | – |
helpful, reply, attributesVote counts, the merchant reply and per-feature ratings from 1 to 5. | { up; down }, { author; body; createdAt? }, Record<string, number> | – |
| Taste | Aktion |
|---|---|
| Tab | Moves through histogram bars, toolbar, reviews, photos and votes. |
| EnterSpace | Applies or clears a rating filter, toggles With photos or a vote. |
| ArrowLeftArrowRight | Chooses a star in the rating input, or moves between photos in the lightbox. |
| Escape | Clears the review search, or closes the lightbox and the review form. |
- Stars are one image named “Rated 4.6 out of 5”, not five separate icons. The rating input is a radio group whose stars read “4 stars, Very good”.
- Histogram bars are toggle buttons with aria-pressed and names like “5 stars, 812 reviews, 63%”. A polite live region announces how many reviews match after each filter change.
- Votes are toggle buttons that read their count. A failed vote is announced as an alert and the count returns to what it was.
- Revealing a review from the lightbox and loading more reviews move focus to the review, so keyboard users land where the content is. Every transition has a reduced-motion version, and selection never relies on color alone.
Gebaut mit
Die kostenlosen HextaUI-Komponenten, aus denen Reviews besteht. Jede lässt sich einzeln installieren.
Code
10 Dateien, hinzugefügt zu components/blocks/reviews.