seo(copy): query-driven titles, descriptions and FAQ for the money pages - #239
Open
BSalaeddin wants to merge 1 commit into
Open
BSalaeddin wants to merge 1 commit into
BSalaeddin wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Text/metadata-only edits to the money pages (home, /pricing, /supported-stores, /coupons, /coupons/[store]) plus three FAQ entries, every one motivated by a Search Console number from the 90-day pull. No layout changes, no new sections, no new dependencies, no rating/review markup.
Stacked on #233 (
seo/claim-integrity) — merge after it, then retarget/merge this one. It builds on the reconciled figures that PR introduced ("4,000+ stores", "100,000+ coupon codes", past-tense Honey wording) and uses no other numbers.Source:
caramel-artifact/seo-2026-09-11/query-brief.md(query clusters computed from the raw GSC pull, 90 days to 2026-09-11),STATE.md(baseline),claim-inventory.md§"Store count claims".Protect the position-2 cluster
The home page owns the "honey alternative" cluster: 40 queries, 2,358 impressions, 187 clicks at position ~2.3 (
honey alternative extension615 impr / pos 2.3,honey extension alternative404 / 2.3,honey app alternative158 / 2.7,extensions like honey143 / 3.0,apps like honey127 / 4.0,best honey alternative extension76 / 2.4,paypal honey alternative36 / 5). That is most of the property's clicks (920 total). Every edit below was checked against one rule: nothing that carries this cluster leaves the page.<title>(and OG title); "alternative to Honey" stays in the hero copy and the existing FAQ untouched.<title>and the meta description — the "extension" / "app" / "alternative" vocabulary is preserved and extended, never swapped.Change table
/(src/app/layout.tsx)<title>+og:titleCaramel | The Trusted Alternative To Honey For Finding Coupons(62) →Caramel: Free Coupon Extension & Trusted Honey Alternative(58)coupon extension117 impr / pos 10.2,best coupon extension25 / 9.4,coupon browser extension19 / 15.8); "Caramel" stays first (caramel extension237 impr / pos 1.3, 33% CTR)./og:descriptionOpen-source, privacy-first coupon extension that finds and applies the best codes at checkout — without selling your data or hijacking creators' commissions.(157) →Free, open-source coupon extension and app for Chrome, Firefox, Edge & Safari — the privacy-first Honey alternative that applies the best codes at checkout.(156)caramel app(67 impr / pos 6.0 / 1 click) and the browser list forcaramel chrome(28 / 4.3) and the Safari cluster (coupon extension safari63 / 9.7,safari coupon extension37 / 10.6,best coupon extension for safari9 / 8.1). All four browsers are live listings (src/lib/brandLinks.ts)./pricing(pricing/page.tsx)<title>Caramel Pricing | Free Forever Coupon Extension(47) →Is Caramel Free? Yes — Free Forever & Open Source | Caramel(59)caramel extension71 impr,caramel coupon extension46,caramel coupon30,caramel coupons24) where home already ranks #1, so the snippet competed with home; it now states the one thing the page answers./pricingCaramel is 100% free, open source, and privacy-first. No hidden fees, no data selling, no credit card required. Save money with the trusted alternative to Honey.(161) →Yes, Caramel is free forever: no premium tier, no hidden fees, no credit card. An open-source coupon extension for 4,000+ stores that never sells your data.(156)/supported-stores(supported-stores/page.tsx)<title>Caramel | Supported Stores(26) →4,000+ Supported Stores — Caramel Coupon Extension(50)/supported-storesExplore the stores supported by Caramel and start saving with our coupon extension.(83) →Search the 4,000+ online stores where the free Caramel coupon extension finds and applies promo codes at checkout, and see the stores added most recently.(154)Is your favourite store supported?untouched./coupons(coupons/page.tsx)Browse coupon codes and promo codes for your favorite stores. Caramel finds and applies the best deals automatically at checkout.(129) →Browse Caramel coupon codes and promo codes for 4,000+ online stores. The free Caramel extension finds and applies the best codes automatically at checkout.(156)caramel coupons/caramel coupon; the description now carries the brand phrase and the reconciled count. Title untouched (tests/unit/coupons-index-page.test.tspins its prefix)./coupons/[store](coupons/[store]/page.tsx)<title>/og:title/twitter:titlewhentotal > 0michaels.com Coupons & Promo Codes | Caramel→michaels.com coupons & promo codes — 74 active codes | Caramel(singular1 active code)<store> promo codequeries (michaels promo code12 impr / 53.6,helmut lang promo code13 / 28.4,mypillow promo code13 / 38.8,books a million coupon code11 / 39.6). Uses ONLY data the page already renders — base domain + the livetotalthe prose section already states — no invented display names or dates./coupons/[store]total > 0Find michaels.com coupon codes, promo codes, and discounts — refreshed as new codes are found.→Caramel lists 74 active coupon codes for michaels.com — promo codes and discounts refreshed as new codes are found and dead ones retired.total === 0(noindex) page keeps the old title and description exactly, pinned by a new assertion. "verified" stays out (removed by #233)./FAQ (src/components/FaqSection.tsx)honey coupons187 / 8.9,honey coupon123 / 11.2,honey coupon finder48 / 11.2,honey code finder38 / 9.7). Serves them truthfully without pretending to be Honey. Facts = the existing FAQ/Features claims (open source scoped to extension + web app, no affiliate code)./FAQsimplycodes vs honey56 impr / pos 9.6 +honey vs simplycodes13 / 10.8, no page targets them. The one claim about SimplyCodes is an absence verified today: simplycodes.com (200, 284 KB) links no source code / GitHub anywhere — the same testclaim-inventory.mdapplies to Honey, Capital One Shopping, Rakuten and Coupert (F14). Their/aboutwas a Cloudflare challenge today, so nothing from it is quoted./FAQcoupon extension safari63 / 9.7,safari coupon extension37 / 10.6,best coupon extension for safari9 / 8.1 — no page targets them. Verified 2026-09-12 by fetchingSAFARI_APP_STORE_URL(apps.apple.com/ke/app/caramel/id6741873881): compatibility lists iPhone "Requires iOS 16.4 or later", iPad, Mac "Requires macOS 13.0 or later" (and Apple Vision). Version numbers deliberately not quoted so the answer does not go stale.The FAQPage JSON-LD is generated from the same array, so the three entries ship in it verbatim;
tests/unit/faq-section.test.tsx(Q/A text must appear verbatim and exactly once in the visible DOM; no rating markup) stays green — the new answers deliberately do not repeat the "over 100,000 coupon codes" / "more than 4,000 online stores" phrases that test matches by regex.Not done, with reason: H1/H2 wording on every page is unchanged (nothing in the data argued for it and the home H1 carries the cluster);
/couponstitle unchanged (already leads with the query; a unit test pins it); no "Chrome" in the home title (58 chars is the budget — "app" and the browser list went into the description instead).Tests updated
tests/unit/coupons-store-page.test.ts— pins the newtotal > 0title/description (singular "1 active code"),og:title === title, and that thetotal === 0page keeps the generic title/description.e2e/seo-a11y.spec.tsonly asserts/caramel/i); grep forTrusted Alternativeacrosse2e/,tests/,src/returns only the twolayout.tsxlines this PR changes.Verification
Run from
C:\wt-caramel-copyon 2026-09-12 afterpnpm install --frozen-lockfile+db:generate(turbo cache bypassed with--forcewhere turbo caches; a first background gate run was killed by the loaded box and re-run in the foreground):pnpm lint --forcecaramel-app:lint: cache bypass, force executing…caramel-extension:lint: ✖ 3 problems (0 errors, 3 warnings)(pre-existingno-consolewarnings in the extension, not touched here) —Tasks: 2 successful, 2 total— exit 0pnpm lint:oxlintapps/caramel-extension/dom-utils.js(block-scoped-var/no-underscore-dangle), 0 errors — exit 0pnpm prettier-check --forcecaramel-app:prettier-check: All matched files use Prettier code style!+ same forcaramel-extension—Tasks: 2 successful, 2 total / Cached: 0 cached— exit 0pnpm --filter caramel-app knippnpm -r run type-checkpackages/caramel-ui type-check: Done,apps/caramel-app type-check: Done,apps/caramel-extension type-check: Done— exit 0pnpm --filter caramel-app test(vitest run)Test Files 78 passed (78)/Tests 719 passed (719)— exit 0 (an earlier 3-file run hit one[vitest-pool-runner]: Timeout waiting for worker to respondon the loaded box; each of the three touched files then passed individually: faq-section 5/5, coupons-store-page 6/6, coupons-index-page 2/2)Rendered lengths (computed, not eyeballed): home title 58, home description 156, pricing title 59, pricing description 156, supported-stores title 50 / description 154, coupons hub description 156.
External facts fetched today with curl:
SAFARI_APP_STORE_URL→ 200, compatibility block lists iPhone (iOS 16.4+), iPad, Mac (macOS 13.0+), Apple Vision;simplycodes.com→ 200 with no source-code / GitHub link (its/aboutreturned a Cloudflare challenge, so nothing from it is used).What CI covers
e2e/seo-regression.spec.ts: per-route<title>> 15 chars and branded, description ≥ 50 chars, exactly one<h1>, canonical/OG/twitter present, titles unique across the public route set (all five titles here are distinct), home raw HTML must contain4,000+and must not contain3,000+/139,000, FAQPage + entity JSON-LD in raw HTML, no aggregateRating anywhere.minVisibleCharscontracts only gain text here (FAQ +3 entries).e2e/home.spec.ts: FAQ heading + first question visible, FAQPage JSON-LD present, no aggregateRating.tests/unit/faq-section.test.tsx,coupons-store-page.test.ts,coupons-index-page.test.tsas above.Owner questions
Caramel: Free Coupon Extension & Honey Alternative(50)./pricingno longer says "alternative to Honey" in its snippet by design (it was cannibalising home). Confirm you are fine with the pricing snippet being purely price-intent.Artifact
C:\Users\alaed\Documents\Github\caramel-artifact\seo-2026-09-11\—query-brief.md(the numbers above),STATE.md,claim-inventory.md.Not verified here
/pricingCTR and thecoupon extension/ Safari query positions against the 2026-09-11 baseline after ~4 weeks.🤖 Generated with Claude Code