Social proof elements (purchase count, trending badge) are factually accurate
Why it matters
Hardcoded 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.
Severity rationale
Medium because hardcoded social proof numbers violate FTC truthful-advertising requirements and diverge silently from actual product performance as time passes.
Remediation
Move all social proof calculations to database aggregation queries in components/SocialProof.tsx — no numeric literals in JSX.
// components/SocialProof.tsx
export async function SocialProof({ productId }: { productId: string }) {
const [purchaseCount, helpfulCount] = await Promise.all([
db.orders.count({ where: { product_id: productId, status: 'completed' } }),
db.reviewVotes.count({ where: { product_id: productId, vote: 'helpful' } })
])
// Only render elements when count > 0 to avoid showing "0 people purchased this"
return (
<div className="social-proof">
{purchaseCount > 0 && <p>{purchaseCount.toLocaleString()} verified purchases</p>}
{helpfulCount > 0 && <p>{helpfulCount} people found these reviews helpful</p>}
</div>
)
}
Search for numeric literals adjacent to words like "purchased", "sold", "reviews", or "trending" in JSX/HTML files and replace each with a live query.
Detection
-
ID:
proof-accuracy -
Severity:
medium -
What to look for: List all social proof elements displayed on product pages (purchase counts, trending badges, "Best Seller" labels, helpful-vote counts). For each, classify whether the displayed value is dynamically calculated from a database query or hardcoded in markup. Count how many are dynamic vs hardcoded. Report the ratio.
-
Pass criteria: At least 100% of social proof numbers (purchase counts, helpful votes, trending indicators) are dynamically calculated from actual database queries — no hardcoded numeric values in JSX/HTML for social proof elements. Report even on pass: list the social proof elements found and confirm each is dynamic.
-
Fail criteria: At least 1 social proof element displays a hardcoded number or string, or a count that does not correspond to a database aggregation query.
-
Skip (N/A) when: The project has no social proof elements (no purchase counts, trending badges, or similar indicators on product pages).
-
Detail on fail:
"2 social proof elements found. 1 of 2 is hardcoded: 'Purchased 500+ times' in JSX markup. The review count is dynamic (from query)."or"'Best Seller' badge applied to all products regardless of actual sales volume." -
Remediation: Calculate social proof dynamically in
components/SocialProof.tsxusing database aggregation queries:// components/SocialProof.tsx export async function SocialProof({ productId }) { const [purchaseCount, reviewCount] = await Promise.all([ db.orders.count({ where: { product_id: productId, status: 'completed' } }), db.reviews.count({ where: { product_id: productId, status: 'approved' } }) ]) return ( <div className="proof"> <p>{purchaseCount} people purchased this</p> <p>{reviewCount} reviews</p> </div> ) }
External references
- external · ftc-endorsement-guides-social-proof — FTC Endorsement Guides — 16 CFR Part 255: Truthful and Non-Deceptive Social Proof
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-reviews·automated