Repository navigation
feat(chat): improve chat plan pricing & funnel - #2845
Conversation
Diagnosis found the chat plans offer's binding constraint was perceived likelihood: abstract "credits/multiplier" copy, no proof, no guarantee, and use-it-or-lose-it framing. The funnel was also blind — chat pricing clicks and paywall impressions weren't tracked. - Translate the credit allowance into concrete "~ N messages" on frontier and fast models via estimateChatPlanMessages() in @llmgateway/shared (estimate anchored to the priciest model in each class, so it's a conservative floor) - Add "Replaces ~$60/mo of ChatGPT Plus + Claude Pro + Gemini" anchor on frontier tiers; lead pricing copy with the dream outcome - Add a 7-day money-back guarantee (refund if barely used — safe against credit arbitrage); reframe credit expiry as "refills every cycle" - Sharpen the tier ladder: accurate Starter model copy (it does not include the GPT-5 family) and a tangible Pro message-count jump - Instrument the funnel: fire pricing_plan_clicked (app:"chat") on CTA clicks and a new chat_pricing_viewed on pricing-page/paywall views Out of scope (flagged for product decision): actual credit rollover, dropping/repricing tiers, and the Starter gpt-5-mini gating fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PHAECqFfWqvGypofGev14U
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughAdds a shared estimator for approximate chat message counts, threads it into pricing plan rendering and analytics, and updates the pricing page and upsell marketing copy. ChangesPricing Copy & Analytics Refresh
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/playground/src/app/pricing/page.tsx`:
- Line 14: The pricing page hero/metadata copy is overstating what the $9
starter tier includes, since it implies access to frontier models like Claude
Opus, GPT-5, Gemini, and Grok even though the Starter plan only offers fast
models. Update the relevant copy in the pricing page content so it clearly
separates the starter tier from higher-tier frontier access, and align the
affected text blocks in the page component to avoid promising features the
Starter plan does not include.
In `@apps/playground/src/components/pricing/chat-plan-upsell.tsx`:
- Around line 52-60: The upsell copy in chat-plan-upsell.tsx overstates what the
Starter tier includes; update the headline and supporting paragraph in the
component to clearly apply only to Plus/Pro or explicitly call out Starter
separately. Use the existing headline/content rendering in chat-plan-upsell to
adjust the marketing copy so it matches the actual plan gating and doesn’t imply
every subscription includes frontier models.
In `@apps/playground/src/components/pricing/chat-pricing-plans.tsx`:
- Around line 38-42: The Starter plan copy in chat-pricing-plans.tsx is
inconsistent with the estimate buckets because it implies “All the fast models”
while the later estimate section treats Claude Sonnet separately from fast
models. Update the Starter plan’s tagline and/or features in the relevant
pricing plan definition so the wording matches the actual bucket structure used
by the message-estimate section, keeping the copy aligned with the plan data in
the pricing plans array.
In `@packages/shared/src/chat-plans.ts`:
- Around line 85-92: The estimateMessages() helper in chat-plans.ts is using
rounding and can return optimistic or negative counts; update it to be
conservative by guarding non-positive creditsUsd up front and using Math.floor()
instead of Math.round() when computing the message estimate. Keep the change
localized to estimateMessages(), preserving the existing perMessage calculation
and returning 0 whenever creditsUsd is not positive or perMessage is
non-positive.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: c1b79913-64f9-4425-9ba9-1dde933abaad
📒 Files selected for processing (5)
apps/playground/src/app/pricing/page.tsxapps/playground/src/components/pricing/chat-plan-upsell.tsxapps/playground/src/components/pricing/chat-pricing-plans.tsxpackages/shared/src/chat-plans.tspackages/shared/src/index.ts
The pricing page, paywall upsell, and plan card implied the $9 Starter tier included frontier flagships (Opus, GPT-5, Gemini Pro, Grok 4), which are gated to Plus/Pro. Separate the tiers in the copy and stop labeling Claude Sonnet as a "fast" model so the wording matches the estimate buckets. Also make estimateMessages() a conservative floor (Math.floor + non-positive guard). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Why
Diagnosed why the chat plans offer (Starter $9 / Plus $19 / Pro $49, shipped Jun 8) wasn't converting. Real data (PostHog, LLMGateway project): 7 conversions in ~3 weeks — 4 Plus, 3 Starter, 0 Pro against ~106 monthly active playground users.
Running the value equation, the binding constraint was perceived likelihood: the offer asked buyers to value abstract "credits / 2.5× multiplier" with no proof, no guarantee, and use-it-or-lose-it expiry framing. The funnel was also blind — chat pricing clicks and paywall impressions weren't tracked, so there was no way to see where it leaked.
What changed
Make the value believable (the #1 lever)
estimateChatPlanMessages()in@llmgateway/shared.Risk reversal + expiry reframe
Sharpen the tier ladder
Instrument the funnel
pricing_plan_clickedwithapp: "chat"on CTA clicks (mirrors the existing dev-plans event, so chat joins the same funnel).chat_pricing_viewedevent on pricing-page and paywall views (sourcedistinguishes them), making paywall impressions measurable for the first time.Out of scope (flagged for a product decision)
gpt-5-minigating — the blocked-pattern"gpt-5"also blocksgpt-5-mini/gpt-5-nanoby substring. Copy is now accurate; whether to grant those cheap models to Starter is a product call.Testing
turbo run build --filter=playground✅ (builds@llmgateway/sharedfirst)pnpm format✅ · pre-commit lint-staged ✅🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Analytics
Bug Fixes