Guide
Component Kit
Four ready-to-use Vue components — ReviewStars, ReviewCard, ReviewList, ReviewSummary.
nuxt-reviews ships four zero-dependency Vue components that are auto-registered globally. No imports needed — use them directly in any template.
ReviewStars
Renders a star rating with full, half, and empty stars.
<ReviewStars :rating="4.5" size="md" />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
rating | number | — | Rating value (e.g. 4.5) |
max | number | 5 | Maximum stars |
size | 'sm' | 'md' | 'lg' | 'md' | Star size |
Size Reference
| Size | Pixels |
|---|---|
sm | 14×14 |
md | 20×20 |
lg | 28×28 |
ReviewCard
Displays a single review with author, rating, date, text, and optional business response.
<ReviewCard
:review="review"
:show-provider="true"
:show-response="true"
:truncate="200"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
review | NormalizedReview | — | Review object |
showProvider | boolean | false | Show provider name (e.g. "via google") |
showResponse | boolean | true | Show business response if present |
truncate | number | 0 | Truncate review text after N characters (0 = no truncation) |
ReviewList
Renders a responsive grid of ReviewCard components. Supports custom slots.
<ReviewList
:reviews="reviews"
:loading="pending"
:columns="2"
show-provider
:truncate="180"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
reviews | NormalizedReview[] | — | Array of reviews |
loading | boolean | false | Show loading state |
emptyText | string | 'No reviews yet.' | Message when reviews is empty |
showProvider | boolean | false | Show provider badge on each card |
showResponse | boolean | true | Show business responses |
truncate | number | 0 | Truncate review text |
columns | 1 | 2 | 3 | 1 | Grid columns (responsive — collapses on mobile) |
Slots
| Slot | Props | Description |
|---|---|---|
#loading | — | Custom loading state |
#empty | — | Custom empty state |
#review | { review } | Custom card per review |
<ReviewList :reviews="reviews" :loading="pending">
<template #loading>
<div>Loading your reviews…</div>
</template>
<template #review="{ review }">
<!-- Completely custom card -->
<MyCustomCard :review="review" />
</template>
</ReviewList>
ReviewSummary
Displays the aggregate score with a large average number, star rating, and star distribution bar chart.
<ReviewSummary
:aggregate="aggregate"
title="Guest Reviews"
:show-distribution="true"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
aggregate | AggregateRating | — | Aggregate data from useReviews() |
title | string | — | Optional heading above the score |
showDistribution | boolean | true | Show star distribution bars |
Full Example
<script setup lang="ts">
const { reviews, aggregate, pending } = useReviews()
useReviewSchema(reviews, aggregate, {
name: 'Grand Hotel Istanbul',
type: 'Hotel',
url: 'https://example.com',
})
</script>
<template>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Sidebar: summary + stars demo -->
<div class="space-y-4">
<ReviewSummary :aggregate="aggregate" title="Guest Reviews" />
<div>
<p class="text-sm font-medium mb-2">Star sizes:</p>
<ReviewStars :rating="aggregate?.average ?? 0" size="sm" />
<ReviewStars :rating="aggregate?.average ?? 0" size="md" />
<ReviewStars :rating="aggregate?.average ?? 0" size="lg" />
</div>
</div>
<!-- Main: review list -->
<div class="md:col-span-2">
<ReviewList
:reviews="reviews"
:loading="pending"
:columns="1"
show-provider
:truncate="300"
/>
</div>
</div>
</template>
Styling
Components ship with minimal scoped CSS using plain color values — no utility class dependency. Override styles by targeting the BEM class names in your own CSS:
/* Example overrides */
.review-card { border-radius: 1rem; }
.review-stars { color: #10b981; } /* change star color */
.review-summary__fill { background: #6366f1; } /* change bar color */