---
title: Review Summary
description: The reviews of a product at a glance — the average as stars, the count, and how the stars are distributed, each row a filter for the reviews below.
visibility: guest
draft: false
---

# Review Summary

`<x-wirekit::review-summary>` shows the reviews of a product at a glance: the average as stars, how many reviews there are, and how the stars are distributed from five down to one. A row of the distribution can lead to the reviews with that many stars.

The reviews themselves are [reviews](/components/review).

## Usage

Give the summary the average and the distribution, the number of reviews for each step:

:::preview{title="The average, the count and the distribution"}
<x-wirekit::review-summary :average="4.6" :distribution="[5 => 82, 4 => 30, 3 => 9, 2 => 4, 1 => 3]" />
:::

The count is the sum of the distribution. Pass `count` when it is larger, because reviews without stars count as well. Each bar shows its step's share of the reviews with stars.

The share reaches each bar as an [inline style](/getting-started/integration#style-attributes-need-style-src-attr). A `style-src` policy that allows no style attributes drops it, and the bars then stay empty while the numbers beside them still say how many.

## Filtering the Reviews by Stars

Give `filters` an address for each step. A row with one is a link to the reviews with that many stars, and `current` marks the step the list shows now:

:::preview{title="Rows that filter the reviews"}
<x-wirekit::review-summary
    :average="4.6"
    :distribution="[5 => 82, 4 => 30, 3 => 9, 2 => 4, 1 => 3]"
    :filters="[5 => '?stars=5', 4 => '?stars=4', 3 => '?stars=3', 2 => '?stars=2', 1 => '?stars=1']"
    :current="4"
/>
:::

A link keeps the filter in the address, so it works without a script and survives a reload. A Livewire page reads the parameter, `#[Url] public ?int $stars = null;`, and passes it back as `current`.

## How Reviews Are Checked

In the EU, a shop that shows customer reviews has to say whether and how it makes sure they come from customers who actually used or bought the product: Directive (EU) 2019/2161, in Germany § 5b (3) UWG. The `notice` slot puts that statement under the distribution, where it is read with the reviews. What it says depends on what the shop does, so WireKit does not write it:

:::preview{title="With the statement on how reviews are checked"}
<x-wirekit::review-summary :average="4.2" :distribution="[5 => 12, 4 => 8, 3 => 2, 2 => 1, 1 => 1]">
    <x-slot:notice>Reviews marked as a verified purchase come from customers who bought the product in this shop. Other reviews are not checked.</x-slot:notice>
    <x-slot:actions>
        <x-wirekit::button size="sm" intent="neutral" surface="outline">Write a review</x-wirekit::button>
    </x-slot:actions>
</x-wirekit::review-summary>
:::

## No Reviews Yet

Without reviews the summary says so, instead of an average of nothing:

:::preview{title="A product without reviews"}
<x-wirekit::review-summary :distribution="[]" />
:::

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `average` | `float\|null` | `null` | The mean score, drawn as stars and written with one decimal. Without reviews nothing is drawn |
| `count` | `int\|null` | `null` | The number of reviews. Null takes the sum of the distribution |
| `distribution` | `array` | `[]` | Stars => number of reviews, `[5 => 82, 4 => 30, …]`. A missing step counts 0; a step outside the scale or a count that is not a whole number of zero or more is reported and left out |
| `max` | `int` | `5` | The top of the scale, as on [rating](/components/rating) |
| `filters` | `array` | `[]` | Stars => the address of the reviews with that many stars. A row with one is a link |
| `current` | `int\|null` | `null` | The stars the list is filtered by: its row is marked as current |
| `scope` | `string\|null` | `null` | Scoped personalization key |

## Slots

| Slot | Description |
| --- | --- |
| `notice` | The statement on how the reviews are checked, under the distribution |
| `actions` | Actions beside the reviews, such as a button to write one |

## Accessibility

- **The score is read once, with its scale.** The stars are an image named "4.6 out of 5 stars", followed by the count as text; the large number repeats the stars and is hidden from assistive technology.
- **The distribution is a list of sentences.** Each row reads "5 stars: 82 reviews", and its bar, its number and its star, which only repeat that, are hidden from assistive technology.
- **A filter row is a link named by its sentence**, and the current one is announced as current and drawn with an outline as well as its fill, so it does not rest on color.
- **On a touch surface every filter row is at least 44px tall.**

## Keyboard Interaction

| Key | Action |
| --- | --- |
| <kbd>Tab</kbd> | Moves to the next filter row, then to the actions |
| <kbd>Enter</kbd> | Follows the focused filter row |

## Design Tokens

| Token | Use |
| --- | --- |
| `--text-wk-3xl` | The average |
| `--color-wk-text` + `--color-wk-bg-muted` | A bar and its track |
| `--color-wk-text-muted` | The count, the numbers of the rows, the notice |
| `--color-wk-bg-active` + `--color-wk-border-strong` | The current filter row: its fill and its outline |
| `--color-wk-bg-hover` | A filter row under the pointer |
| `--radius-wk-sm` + `--radius-wk-full` | A row, and the ends of a bar |
