I call the stars in search results the shortest path to increasing trust before the click. AggregateRating – this is a schema.org structure that describes an aggregated rating of an item: a product, service, or place. Essentially, it’s a way to pass to the search engine the formula ‘how many ratings + what average’ to get a rich snippets rating — visual stars next to your snippet in search.
Typical use cases are simple:
- products in an online store (Product): product cards and collection pages.
- Services (Service) and digital products (SoftwareApplication).
- LocalBusiness: branch pages, menus, pricing pages. However, Google limits showing stars for local entities themselves: below I’ll explain how to use this to your advantage.
- Content from collections: subcategories and playlists (if each item has its own review object).
How Google displays ratings in search results

Google Rich Results adhere to strict requirements. First, the entity type must support ratings (Product, Recipe, SoftwareApplication, Book, Movie and a number of others). Second, the data must be reliable: ratingValue, the actual average, reviewCount — the real number of reviews, and the reviews themselves must be available on the page or via click. Third, the source must be trustworthy: unique, verifiable reviews and a transparent moderation policy.
Google shows stars more often when:
- The page type — Product or Recipe — has a clear reviews block, and ratingValue and reviewCount are consistent.
- Reviews are regularly updated and do not look synthetic (originate from crm, Prom.ua/Rozetka, Google Business Profile, Trustpilot).
- The page renders quickly; Googlebot sees the JSON-LD without long waiting.
AggregateRating: reviewCount, ratingValue

Key fields of schema.org AggregateRating:
- ratingValue, the average rating (a decimal number, e.g. 4.6). It is recommended to set precision to one decimal place.
- reviewCount – number of ratings (integer). Should be synchronized with the reviews registry.
- bestRating: maximum scale value (often 5). If not specified, some validators assume 5.
- worstRating: minimum scale value (usually 1).
- itemReviewed: a reference to the item (Product, Service, LocalBusiness, SoftwareApplication, etc.) the rating applies to.
- ratingValue – a number in the range [worstRating; bestRating].
- reviewCount – no less than the actual number of available reviews.
- If there are Review objects on the page, their count and average must correspond to the AggregateRating.
- In JSON-LD avoid mixing types and contradictions (for example, different ratingValue in two blocks).
Example of AggregateRating in JSON-LD
Below is a minimal valid example for a product with reviews. I use JSON-LD format for its resilience to layout changes and Google support.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Antiseptic hand gel, 250 ml",
"sku": "SKU-AG-250",
"brand": {
"@type": "Brand",
"name": "CleanCare"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "128",
"bestRating": "5",
"worstRating": "1"
},
"review": [
{
"@type": "Review",
"author": {
"@type": "Person",
"name": "Olena"
},
"datePublished": "2025-01-18",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5",
"bestRating": "5",
"worstRating": "1"
},
"reviewBody": "Convenient dispenser, neutral scent. Nova Poshta delivery arrived the next day."
}
]
}
Example of Product schema with AggregateRating
The product with AggregateRating has already been covered. For LocalBusiness the logic is different: Google does not encourage self-serving reviews for organizations and local businesses on their own sites. In practice this means: the rating on the branch’s own page often remains without stars in search results. Therefore I apply a strategy of marking up ratings at the level of services/offers, not the organization.
Example for a local business service page:
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Ultrasound diagnostics",
"provider": {
"@type": "LocalBusiness",
"name": "Medical Center in Pechersk"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.8",
"reviewCount": "86",
"bestRating": "5",
"worstRating": "1"
}
}
JSON-LD, Microdata or RDFa for star ratings

I recommend JSON-LD for AggregateRating for three reasons:
- Ease of implementation and maintenance: not tied to the HTML structure, can be generated by the server, via a headless CMS or Shopify/WordPress plugins.
- Google support: Rich Results Test consistently reads JSON-LD even with dynamic rendering.
- Caching and CDN: an independent block is easy to version and to cache at the template level and in CI/CD.
How to get stars in search results

Step 1. Source of ratings. I start with an inventory: where the reviews are stored — CRM, online store, Prom.ua, Rozetka, Google Business Profile, Trustpilot, custom forms? Marketing agrees on a moderation policy and data quality criteria, development configures anti-fraud triggers: email/phone verification, rate limits, basic click signature.
Step 2. Generating JSON-LD. We design the schema for Product/Service/SoftwareApplication, normalize ratingValue and reviewCount, add review objects. For large catalogs it is useful to automate generation of AggregateRating via a pipeline from the database and marketplace APIs. Insertion: at the page template level, with versioning.
Step 3. Testing. I run every template through Rich Results Test and Schema Markup Validator, ensuring there are no critical errors. I treat warnings with common sense: if a field is optional, we’ll add it in the next release.
Step 4. Deploy and monitoring. In CI/CD we include unit tests for JSON-LD (snapshots, regular expressions) and e2e checks, as well as logging of microdata errors. After release I monitor the appearance of stars in the SERP and the correlation of CTR/CR.
- Marketing: sources of reviews, moderation policy, legal section on personal data.
- Development: correct types, no duplicates, validators in CI, fallback for empty data.
- SEO: sitemap of pages with supported types, monitoring in Google Search Console.
Implementation for dynamic rendering
In React/Vue projects I prefer server-side JSON-LD. In SSR frameworks (Next.js, Nuxt) we inject the markup on the server so Googlebot sees it without waiting for rendering. For client-side rendering, pre-rendering or dynamic rendering that serves a pre-rendered snapshot to the bot helps.
- Server-side JSON-LD during SSR.
- Pre-rendering critical catalog pages.
- Dynamic rendering as a temporary measure for complex UI.
Microdata: checks and checklists

I rely on four tools: Rich Results Test, Schema Markup Validator, the deprecated Structured Data Testing Tool (for quick local checks) and the Structured Data report in Google Search Console. Validation errors are to be taken literally: type mismatches, invalid values, missing required fields. Warnings: suggestions for improvements.
- Unit tests for JSON-LD generation (comparison with reference snapshots).
- E2E rendering tests (check for presence of script type=”application/ld+json”).
- Staging with validators enabled and manual acceptance.
- Rollback strategy: a separate version of the schema, the ability to roll back without affecting the product page.
How to fix rating microdata
- Mismatch of reviewCount with the page interface. Solution: synchronize the counter with the database/visible reviews and update it via cron/event.
- ratingValue with three decimal places or “5/5” as a string. Solution: convert to a number and format X.Y.
- Duplicate markups: JSON-LD and Microdata with different values. Solution: keep one format, usually – JSON-LD.
- Stale values after migration to a new CMS. Solution: schema versioning, smoke tests in CI.
Reasons for missing stars: few reviews (especially 1–2, without real texts), unsupported type, hidden reviews, poor rendering for Googlebot. Prevention is helped by strict validation, monitoring and clear aggregation rules. In cases with manual action we cleaned sources, removed dubious reviews, documented the moderation policy: restoring visibility returned normal CTR within 2–8 weeks.
Integration of reviews and rating aggregation
The working architecture looks like this: intake of reviews from forms and external sources (Google Business Profile, Trustpilot, Facebook Reviews, TripAdvisor, reviews from Prom.ua/Rozetka), normalization (unified 1–5 scale), storage with change audit and aggregation for schema. BUSINESS SITE specialists recommend storing ‘raw’ data and computing aggregates on the fly or on a schedule for transparency.
Scaling and automation of the catalog
- Cron processes for periodic updating of AggregateRating (daily/hourly).
- Event-driven updates when new reviews appear (event on the event bus → recalculation).
- Streaming for marketplaces with frequent changes.
Architecturally, caching (in-memory/Redis), a CDN for static assets and structured data versioning help. If there is no data, we enable fallback logic: do not display AggregateRating and offer alternative CTAs (subscribe to a review / ask questions about the product). For Shopify/WordPress, we use plugins as a base, adding custom hooks for synchronization and normalization.
Fallback logic when there are no reviews
When there are no reviews, I recommend:
- Do not display AggregateRating, and instead show social proof: “Be the first to rate the product”, guarantees from PrivatBank/Monobank, delivery speed by Nova Poshta.
- Maintain schema versioning: store the previous valid version and the ability to roll back in case of aggregation errors.
- Schedule a trigger to notify marketing: “products without reviews” and priorities for collection.
Monitoring star ratings in SERPs and analytics
I set up three levels of monitoring:
- Google Search Console: I track rich results and structured data errors.
- Third-party SERP trackers and periodic Screaming Frog crawls with JSON-LD exports.
- Change logs: when and for which SKUs reviewCount/ratingValue were updated.
Google doesn’t show stars after schema
My troubleshooting sequence is as follows:
- Structured Data Validator and Rich Results Test, no errors.
- Compliance with Google’s rules: supported type, no self-serving for LocalBusiness.
- Sufficient number of real reviews and reviewCount matching the interface.
- No duplicates and no conflicts with canonical.
Diagnostics via Google Search Console Structured Data will quickly indicate which templates have the problem. Common fixes: remove the second markup (Microdata), align ratingValue with the actual average, remove unsupported fields, synchronize dates and sources, clean the markup of reviews that violate policies. If a manual action has been received, I prepare a document with fixes, a moderation policy and request a review: BUSINESS SITE practice shows that a clear, honest argumentation speeds up the lifting of sanctions.
Data security and fraud
Organization of work in the company
Roles map:
- Marketing: collection and incentivization of reviews, moderation policy, communication with platforms (Prom.ua, Rozetka, Google Business Profile).
- Development – generation and validation of JSON-LD, CI/CD, logging of markup errors.
- SEO – strategy for schema types, page prioritization, monitoring of rich results.
- Legal department: compliance with advertising and data protection laws.
- Support service: initial verification of reviews.
Templates for developers and marketing
JSON-LD template for a product:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Product name",
"sku": "SKU-XXXX",
"brand": { "@type": "Brand", "name": "Brand" },
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.5",
"reviewCount": "57",
"bestRating": "5",
"worstRating": "1"
}
}
JSON-LD template for a local business service page:
{
"@context": "https://schema.org",
"@type": "Service",
"serviceType": "Service name",
"provider": { "@type": "LocalBusiness", "name": "Branch name" },
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.7",
"reviewCount": "93",
"bestRating": "5",
"worstRating": "1"
}
}
- JSON-LD validation in CI.
- No duplicate markup.
- Single source of truth and versioning.
- Staging + Rich Results Test before release.
- Rollback without affecting the UI.
Checklist for marketing:
- Moderation and anti-fraud policy.
- Feedback collection plan (after payment/delivery via Nova Poshta, email sequences from PrivatBank/MonoBank).
- Map of external review sources and attribution.
- Visibility threshold (minimum N reviews before activating the block in the SERP).
An example of fixing the error “different ratingValue in markup and UI”: we moved the average calculation to a single module, synchronized rounding to one decimal place and removed Microdata, leaving only JSON-LD; the stars appeared within 5–10 days.
Frequently Asked Questions
Answer: There is no universal number, but in BUSINESS SITE’s experience pages with 8–15 reviews and text comments work reliably. Actions: encourage collecting reviews after delivery by Nova Poshta, launch e-mail reminders, synchronize sources.
Answer: Yes, with correct attribution of the source and compliance with their rules. Examples: Google Business Profile, Trustpilot, Prom.ua, Rozetka. Legally it’s important to have consent for use and a link to the original source.
Answer: Run the structured data validator and the Rich Results Test, check the entity type and review sources, remove duplicates. Then, GSC Structured Data, synchronize reviewCount/ratingValue and speed up rendering for Googlebot.
Answer: Set up a pipeline: cron + event-driven recalculation on new reviews, JSON-LD caching, delivery via CDN, tests in CI/CD and checks on staging. Once a day – background reconciliation of counters.
Answer: Manual actions (manual actions), loss of domain trust and a drop in rich results. Preventive measures: anti-fraud review checks, transparent moderation, source audits.










