From ed44c7278c944021bcaa2737281123838c111dbb Mon Sep 17 00:00:00 2001
From: Alaeddin <15094821+BSalaeddin@users.noreply.github.com>
Date: Sat, 12 Sep 2026 02:10:25 +0100
Subject: [PATCH] fix(copy): truthful catalog figures and privacy/Honey wording
(claim integrity)
---
README.md | 6 ++---
apps/caramel-app/e2e/home.spec.ts | 2 +-
apps/caramel-app/e2e/pages.spec.ts | 2 +-
apps/caramel-app/e2e/seo-regression.spec.ts | 27 +++++++++++++++++++
.../app/(marketing)/coupons/[store]/page.tsx | 8 +++---
.../src/app/(marketing)/coupons/page.tsx | 8 +++---
.../src/app/(marketing)/sources/page.tsx | 2 +-
apps/caramel-app/src/app/llms.txt/route.ts | 8 +++---
.../caramel-app/src/components/FaqSection.tsx | 10 ++++---
.../src/components/FeaturesSection.tsx | 22 +++++++--------
.../src/components/HeroTicketScene.tsx | 4 +--
.../src/components/OpenSourceSection.tsx | 11 ++++----
.../src/components/PricingSection.tsx | 10 +++----
.../src/components/SupportedSection.tsx | 4 +--
apps/caramel-app/src/components/WhyNot.tsx | 27 +++++++++++--------
.../components/coupons/coupons-section.tsx | 8 +++---
apps/caramel-app/src/lib/heroStats.ts | 4 +--
.../tests/unit/faq-section.test.tsx | 8 +++---
18 files changed, 102 insertions(+), 69 deletions(-)
diff --git a/README.md b/README.md
index f2d257cb..7ec3f6fc 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
# Caramel - Trusted Coupon Finder
**Caramel is the open‑source, privacy‑first alternative to Honey.**
-It automatically tests codes at checkout, never sells your data, and never overwrites creators’ affiliate links. Today Caramel already supports more than **5 000 stores**. You can find even more information at https://grabcaramel.com.
+It automatically tests codes at checkout, never sells your data, and never overwrites creators’ affiliate links. Today Caramel already supports more than **4,000 stores**. You can find even more information at https://grabcaramel.com.
@@ -14,8 +14,8 @@ It automatically tests codes at checkout, never sells your data, and never overw
## Why choose Caramel?
- **100% open source** – every release is on GitHub for public audit
-- **Privacy first** – the extension only asks for tab access while you shop, nothing more
-- **Real‑time savings meter** – see exactly how much a coupon saves you before you commit
+- **Privacy first** – the extension asks only for the permissions it needs to find the store you're on, read the checkout page and apply codes (tabs, storage, sign-in) – no ads, no third‑party trackers
+- **Real‑time savings meter** – see exactly how much each code saved as it is tested
- **Creator‑friendly** – Caramel keeps existing affiliate links intact so influencers get the credit they deserve
- **Community‑powered** – join our Discord, file issues, or open PRs to make Caramel even sweeter
diff --git a/apps/caramel-app/e2e/home.spec.ts b/apps/caramel-app/e2e/home.spec.ts
index 15115d7e..8e16c9bf 100644
--- a/apps/caramel-app/e2e/home.spec.ts
+++ b/apps/caramel-app/e2e/home.spec.ts
@@ -55,7 +55,7 @@ test.describe('Home Page - Critical Sections', () => {
page.getByRole('heading', { name: 'Creator-Friendly' }),
).toBeVisible()
await expect(
- page.getByRole('heading', { name: 'Lightning Fast' }),
+ page.getByRole('heading', { name: 'Fast & Lightweight' }),
).toBeVisible()
await expect(
page.getByRole('heading', { name: 'Cross-Browser Support' }),
diff --git a/apps/caramel-app/e2e/pages.spec.ts b/apps/caramel-app/e2e/pages.spec.ts
index 6daa747c..dd8f1fab 100644
--- a/apps/caramel-app/e2e/pages.spec.ts
+++ b/apps/caramel-app/e2e/pages.spec.ts
@@ -7,7 +7,7 @@ test.describe('Coupons Page', () => {
await expect(
page.getByRole('heading', {
level: 1,
- name: /verified coupon codes/i,
+ name: /today's coupon codes/i,
}),
).toBeVisible()
await expect(page.getByText(/browse.*coupon/i).first()).toBeVisible()
diff --git a/apps/caramel-app/e2e/seo-regression.spec.ts b/apps/caramel-app/e2e/seo-regression.spec.ts
index ac55dffa..a686f408 100644
--- a/apps/caramel-app/e2e/seo-regression.spec.ts
+++ b/apps/caramel-app/e2e/seo-regression.spec.ts
@@ -223,6 +223,33 @@ test.describe('SEO regression gate (raw server HTML)', () => {
expect(types).toContain('"@type":"SoftwareApplication"')
})
+ // Claim-integrity pin (2026-09-11): the two catalog figures the site is
+ // allowed to quote are "4,000+ stores" and "100,000+ coupon codes",
+ // rounded DOWN from prod on that date (4,314 store pages in sitemap.xml,
+ // 107,827 from GET /api/coupons?limit=1 → total). Both are static copy
+ // (heroStats.ts, FaqSection.tsx, PricingSection.tsx, SupportedSection.tsx)
+ // so this holds in both e2e contexts. The negative pin is the retired
+ // "139,000" FAQ number that outlived the stats-census change for six
+ // weeks — a figure must never drift back silently. Re-verify the live
+ // counts before changing either string; never round up.
+ test('home raw HTML quotes only the reconciled catalog figures', async ({
+ page,
+ }) => {
+ const html = await (await page.request.get('/')).text()
+ expect(html, 'store count must read 4,000+').toContain('4,000+')
+ expect(html, 'coupon count must read 100,000').toContain(
+ 'over 100,000 coupon codes across more than 4,000 online stores',
+ )
+ expect(
+ html,
+ 'retired FAQ figure 139,000 must not reappear',
+ ).not.toContain('139,000')
+ expect(
+ html,
+ 'superseded store count 3,000+ must not reappear',
+ ).not.toContain('3,000+')
+ })
+
test('robots.txt honours the env-aware indexing contract', async ({
baseURL,
page,
diff --git a/apps/caramel-app/src/app/(marketing)/coupons/[store]/page.tsx b/apps/caramel-app/src/app/(marketing)/coupons/[store]/page.tsx
index c4927fe9..df150e50 100644
--- a/apps/caramel-app/src/app/(marketing)/coupons/[store]/page.tsx
+++ b/apps/caramel-app/src/app/(marketing)/coupons/[store]/page.tsx
@@ -92,7 +92,7 @@ export async function generateMetadata({
// here or these pages share links with no preview image at all.
const banner = `${baseUrl}/caramel_banner.png`
const title = `${base} Coupons & Promo Codes | Caramel`
- const description = `Find verified ${base} coupon codes, promo codes, and discounts. Updated daily.`
+ const description = `Find ${base} coupon codes, promo codes, and discounts — refreshed as new codes are found.`
// Canonical always points at the NORMALIZED base-domain URL: this route
// serves the same content for /coupons/www.nike.com, /coupons/shop.nike.com
// and /coupons/nike.com, so every variant must canonicalize to ONE URL or
@@ -238,9 +238,9 @@ export default async function StoreCouponsPage({
codes for that store from its own catalog, tries them in the
promo-code field, and keeps the one with the biggest
discount. It never replaces affiliate links, and it reports
- back only whether a code worked — with no account
- information attached — so code rankings stay accurate for
- every shopper.
+ back whether a code worked (linked to your account only when
+ you're signed in) so code rankings stay accurate for every
+ shopper.