All 20 checks with why-it-matters prose, severity, and cross-references to related audits.
Without a review submission form, buyers have no path to contribute social proof, and the store loses the user-generated content that drives conversion on product pages. Missing or incomplete forms also break schema.org AggregateRating eligibility, which strips star snippets from Google search results and reduces click-through. Shoppers who cannot review also cannot warn others about defects, so trust signals stagnate and repeat purchase rates drop.
Why this severity: Critical because an absent review form removes the entire user-generated content pipeline that product pages depend on for conversion.
ecommerce-reviews.review-collection.submission-form-existsSee full patternReview volume collapses without a post-purchase prompt because shoppers rarely return unprompted to write reviews, even when delighted. Relying on organic submissions means weeks of sales generate zero new reviews, aggregate ratings stagnate, and new products launch with empty review sections that suppress conversion. The 1-7 day window matters because sentiment fades fast; by week two, recall of product specifics drops and response rates crater.
Why this severity: High because missing prompts directly throttle review volume, which is the primary input to ratings-driven conversion lift.
ecommerce-reviews.review-collection.post-purchase-promptSee full patternWithout a unique constraint on (user_id, product_id), a single user can flood your product with five-star reviews — or a malicious competitor can script hundreds of one-star submissions. CWE-799 (Improper Control of Interaction Frequency) names this exact failure. Beyond rating manipulation, duplicate reviews distort your aggregate score fed to schema.org AggregateRating, poisoning the star display that Google indexes. The fix is two-layer: a database constraint that survives any future code path, plus an application-level check that returns a user-facing error immediately.
Why this severity: High because a missing constraint enables unlimited rating manipulation that corrupts product trust signals and schema.org data without requiring any special privileges.
ecommerce-reviews.review-collection.duplicate-preventionSee full patternWCAG 2.2 SC 4.1.2 (Name, Role, Value) and SC 2.1.1 (Keyboard) require that all interactive controls be operable without a mouse and expose their purpose to assistive technology. A star rating built from styled `<div>` elements with only `onClick` handlers is invisible to screen readers and completely unreachable by keyboard — failing Section 508 2018 Refresh 502.3.1 as well. Users who navigate by keyboard or rely on VoiceOver/NVDA cannot leave a rating at all, which is a measurable drop in review volume and a legal exposure under ADA and EAA for US and EU stores.
Why this severity: Medium because the inaccessible input excludes keyboard and screen-reader users from submitting reviews without enabling a security or data-integrity attack.
ecommerce-reviews.review-collection.star-input-accessibleSee full patternWCAG 2.2 SC 1.3.1 (Info and Relationships) and SC 3.3.2 (Labels or Instructions) require that every form input have a programmatically associated label and that required fields be identified. A review form where labels exist only as placeholder text fails both criteria: placeholders vanish on focus, and screen readers cannot associate floating-label text with the input's purpose. A form that doesn't distinguish required from optional fields produces higher abandonment rates — users guess wrong, get validation errors, and leave. This is particularly acute for star rating inputs and photo upload fields that have no obvious placeholder.
Why this severity: Medium because inaccessible labels break screen reader navigation and increase form abandonment without creating a data or security exposure.
ecommerce-reviews.review-collection.form-fields-labeledSee full patternAn aggregate rating is the single highest-impact trust signal on a product page — multiple e-commerce studies put conversion lift from visible star ratings at 15–40%. Missing or hardcoded aggregates also break schema.org `AggregateRating` structured data (see `ecommerce-reviews.schema-seo.aggregate-rating-schema`), eliminating the review-rich snippet in Google SERPs. Beyond conversion, a hardcoded value is a dark-pattern that regulators including the FTC treat as deceptive when it doesn't reflect real buyer sentiment. The aggregate must be dynamically computed from the approved reviews table to be both accurate and legally defensible.
Why this severity: Critical because an absent or hardcoded aggregate rating directly suppresses conversion, removes Google rich-snippet eligibility, and constitutes a deceptive practice if the displayed score doesn't match real data.
ecommerce-reviews.display-ux.aggregate-rating-visibleSee full patternA review component that omits the author name, submission date, star rating, or review text fails to meet the minimum data required for schema.org `Review` markup (see `ecommerce-reviews.schema-seo.review-schema`), which costs rich-snippet eligibility. Beyond SEO, shoppers use date and author identity to gauge review credibility — an undated review from an anonymous source with no star rating carries near-zero trust weight. Inconsistent field sets across review components also break JSON-LD generation downstream: if some `ReviewItem` instances omit `datePublished` or `reviewRating`, the structured data output will be incomplete for a subset of products.
Why this severity: Medium because missing required review fields degrade trust signals and break schema.org Review markup without creating a security or data-integrity risk.
ecommerce-reviews.display-ux.review-display-completeSee full patternReviews rendered in a single fixed order force shoppers to read chronologically, which buries the most decision-useful content. Negative reviews discovered through sorting drive credibility; a catalog that shows only the oldest or newest feedback reads like curation and erodes trust. Sort controls also let shoppers self-serve the exact signal they need — recency for fast-changing products, helpfulness for depth, rating extremes for risk assessment — so conversion lifts on products with mixed reviews.
Why this severity: Medium because reviews still render without sort, but decision quality and time-to-purchase degrade noticeably on high-volume products.
ecommerce-reviews.display-ux.review-sortingSee full patternOn products with 50+ reviews, shoppers looking to validate a concern — say, "does this fail after six months?" — cannot surface 1-star and 2-star reviews without scrolling through dozens of positives. A star-rating filter lets them find that signal in one click, which increases time-on-page and reduces refund rates because buyers self-disqualify before purchase instead of after. Without filters, low-rated reviews get drowned and the product reads falsely uniform.
Why this severity: Low because filtering is a quality-of-life affordance; reviews are still readable without it, just harder to navigate at scale.
ecommerce-reviews.display-ux.review-filteringSee full patternA product page that fetches all reviews without a `LIMIT` clause will transfer every row in the reviews table on every page load. At 200 reviews averaging 500 bytes each, that's 100KB of JSON for a single product visit — multiplied across concurrent users, this becomes a cost and latency problem. ISO 25010 performance-efficiency requires that resource use be proportionate to demand. More concretely, a product that accumulates 10,000 reviews will eventually time out or OOM the serverless function handling the request, causing a user-visible 500 error at scale.
Why this severity: Low because the performance impact only manifests at high review volumes and does not expose data or allow unauthorized actions at typical early-stage scale.
ecommerce-reviews.display-ux.pagination-lazy-loadSee full patternHelpful-vote mechanisms surface the reviews with the highest signal-to-noise ratio, so shoppers reach useful content faster and conversion climbs. Without votes, long-form detailed reviews sit next to one-line "love it" posts with no way to distinguish quality; community ranking is the cheapest moderation layer that exists. Vote data also feeds the "Most Helpful" sort (WCAG-adjacent discoverability) and trains future review-ranking models.
Why this severity: Low because reviews remain readable without votes, but the sort-by-helpful path and community quality ranking are unavailable.
ecommerce-reviews.display-ux.helpful-votesSee full patternWithout a `status` column defaulting to `'pending'` and a filter on every public display query, your review page is an open broadcast channel — any submitted content, including spam, competitor attacks, and profanity, appears live to all shoppers immediately. CWE-284 (Improper Access Control) covers exactly this: the resource (a published review) is accessible to users who should not have triggered that state transition (published). Even one unfiltered display query is enough to leak pending reviews; attackers simply POST then GET before moderation runs.
Why this severity: Critical because a missing status filter exposes unmoderated, potentially harmful content to all site visitors with no privilege required beyond submitting a review.
ecommerce-reviews.moderation-trust.moderation-enforcedSee full patternA review form with no content filtering is an XSS injection surface (CWE-79, OWASP A03:2021 Injection): stored review text rendered without escaping can execute scripts in other users' browsers. Beyond injection risk, unfiltered review text lets competitors post identical five-star spam 100 times over — the only limit is how fast they can POST. A manual admin review queue without automated pre-filtering creates an unmanageable backlog at any real volume. At minimum, one automated layer (a profanity library or AI moderation API call) must run before the `INSERT` to catch the automated attacks.
Why this severity: High because absent content filtering allows stored XSS via review text and enables unlimited spam submission with no automated defense at any layer.
ecommerce-reviews.moderation-trust.spam-detectionSee full patternAn edit route that updates review text without resetting `status` to `'pending'` creates a post-approval backdoor: a user submits a clean review, it passes moderation, then they edit it to inject harmful content that immediately goes live because the approved status is preserved. CWE-284 (Improper Access Control) applies — the user gains a privilege (bypassing moderation) they were not supposed to retain after the initial approval. This also means edit protection is inseparable from `ecommerce-reviews.moderation-trust.moderation-enforced`: if moderation exists, every write path to review content must re-enter it.
Why this severity: High because a post-approval edit bypass gives any authenticated user a reliable path to publish arbitrary content to live product pages without moderation.
ecommerce-reviews.moderation-trust.edit-protectionSee full patternThe FTC Endorsement Guides (revised 2023) explicitly require that "Verified Purchase" or equivalent indicators be truthful — displaying the badge for reviews from non-buyers is a deceptive endorsement. Beyond legal risk, unverified reviews mixed into the same display as genuine buyer reviews dilute trust: a product with 100% "Verified Purchase" badges where the badge is just hardcoded to `true` will have the label completely reverse-fired when a single fraudulent review is exposed publicly. The `verified_purchase` check must reach into order history at submission time to have any meaning; a database field alone without that query is cosmetic.
Why this severity: Medium because a hardcoded or query-free verified-purchase badge violates FTC endorsement guidelines and misleads shoppers without allowing unauthorized data access.
ecommerce-reviews.moderation-trust.verified-purchaseSee full patternHardcoded social proof numbers — "Purchased 500+ times", "Best Seller", "4.8 stars" — violate the FTC Endorsement Guides on social proof and, when displayed in schema.org markup, cause Google to flag rich results as inaccurate. A product page that shows "Purchased 500+ times" backed by a literal JSX string rather than a database count misrepresents sales volume, which is deceptive advertising under FTC guidelines. The failure compounds as your catalog grows: the hardcoded number never updates, so the gap between claimed and actual performance widens automatically.
Why this severity: Medium because hardcoded social proof numbers violate FTC truthful-advertising requirements and diverge silently from actual product performance as time passes.
ecommerce-reviews.moderation-trust.proof-accuracySee full patternReview image uploads with no file type validation, size limits, or approval gate are a CWE-434 (Unrestricted File Upload) and CWE-79 (XSS) exposure: an attacker can upload an SVG with embedded `<script>` tags or a polyglot file that executes when rendered inline. OWASP A04:2021 (Insecure Design) covers the absence of upload constraints at the design level. Even without malicious intent, a user uploading a 50MB RAW photo file will exhaust serverless function memory and trigger a 500 error for all concurrent visitors. Images served directly from an S3 path with no content-type header enforcement allow MIME-type confusion attacks in older browsers.
Why this severity: Medium because unvalidated image uploads enable stored XSS via SVG polyglots and file-size denial-of-service without requiring elevated privileges.
ecommerce-reviews.moderation-trust.review-images-moderatedSee full patternGoogle requires a valid schema.org `AggregateRating` block to render star ratings in search results (rich snippets). Without it, your product pages compete in SERPs as plain blue links against competitors whose pages show 4.8★ inline — a significant CTR disadvantage. The schema.org `Product.aggregateRating` mapping specifies `ratingValue` must be a number, not a string: submitting `"4.5"` instead of `4.5` causes Google's Rich Results Test to flag the markup as invalid and suppresses the snippet. Hardcoded values are doubly penalised — they diverge from the displayed aggregate over time, which Google can detect by comparing the structured data to the visible page content.
Why this severity: Critical because missing or invalid AggregateRating structured data eliminates star-rating rich snippets from Google SERPs, directly reducing organic click-through rate.
ecommerce-reviews.schema-seo.aggregate-rating-schemaSee full patternIndividual `Review` schema.org blocks make each shopper review eligible for its own rich result — author name, star rating, and date displayed inline in SERPs alongside the product. Without them, your reviews exist only in HTML that search crawlers cannot interpret as structured endorsements. The schema.org `Review.reviewRating` mapping requires `ratingValue` as a number and `author` as a `Person` object with a `name` field — omitting either means Google's parser rejects the block silently. Stores with per-review schema see measurably higher long-tail SERP presence because individual reviews can surface as standalone snippets for "[product] review" queries.
Why this severity: High because absent per-review schema.org markup forfeits rich-result eligibility for every individual review, reducing organic SERP visibility across all long-tail review queries.
ecommerce-reviews.schema-seo.review-schemaSee full patternForcing re-verification on already-authenticated users tanks review submission rates — every extra step compounds drop-off, and CAPTCHA or email re-confirmation on an active session signals distrust of your own auth system. Submissions fall, aggregate ratings shrink, and schema.org AggregateRating eligibility suffers from thin review counts. The friction also pushes users to third-party review platforms where the data leaves your control.
Why this severity: Low because the flow still works, but unnecessary verification steps measurably depress submission completion rates.
ecommerce-reviews.schema-seo.review-email-reauthSee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Reviews & Social Proof Audit