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.
Medium because hardcoded social proof numbers violate FTC truthful-advertising requirements and diverge silently from actual product performance as time passes.
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.
ID: ecommerce-reviews.moderation-trust.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.tsx using 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>
)
}