Skip to content

feat: custom analytics events for pricing CTAs and valuation funnel - #57

Open
sweetmantech wants to merge 1 commit into
mainfrom
feat/1902-marketing-analytics
Open

feat: custom analytics events for pricing CTAs and valuation funnel#57
sweetmantech wants to merge 1 commit into
mainfrom
feat/1902-marketing-analytics

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

recoupable.dev has @vercel/analytics mounted (<Analytics /> in app/layout.tsx) but emitted zero custom events, so the marketing funnel was unmeasurable. This PR adds a thin, tested trackEvent wrapper and wires five client-side funnel events. Purely additive: no hrefs, copy, or styling changed.

Part of recoupable/chat#1902 (M3).

Events

Event Trigger Props
pricing_cta_clicked Click on any pricing-page CTA (three plan cards + bottom "Get started free") plan: plus | pro | partner | free
valuation_artist_selected Visitor picks an artist in the /valuation search artist_name (public artist name)
valuation_run The POST /api/valuation run starts (fires per run, including deferred post-login auto-runs) none
valuation_completed The valuation resolves successfully and the result card renders tracks_measured, duration_ms
open_app_clicked Header "Open app" link (desktop pill + mobile menu row, signed-in state) none

Notes:

  • The issue spec listed plan values free/pro/partner; the live pricing copy has no "free" plan card — the plans are plus/pro/partner (lib/copy/pricing.ts), so plan-card events carry the real plan ids and the bottom "Get started free" CTA reports free.
  • duration_ms shipped: it's measured locally inside the run function (startedAt at POST start), no state threading needed.
  • No PII in any prop: artist names are public figures; visitor emails are never sent.

How

  • lib/analytics/trackEvent.ts — single exported function forwarding to @vercel/analytics track, swallowing errors so a blocked/failed beacon can never break the page. TDD: lib/analytics/__tests__/trackEvent.test.ts (mocked @vercel/analytics; asserts forwarding with and without props, and error swallowing) written first and confirmed red before the implementation.
  • components/pricing/PricingCtaLink.tsx — client anchor wrapper so the server-rendered pricing page can attach onClick without changing the anchor's href, copy, or classes.
  • Valuation events live in components/valuation/CatalogValuation.tsx (select) and hooks/useCatalogValuation.ts (run/completed), so deferred post-login runs are counted too.

Verify in Web Analytics

  1. Open the preview deployment; click a pricing CTA, the header "Open app" pill, and run a /valuation.
  2. Vercel dashboard → recoupable.dev project → Analytics → Events: the five event names appear with the props above (allow a minute for ingestion). In the browser you can also watch POST /_vercel/insights/event requests fire in the Network tab on each interaction.

Test + build

  • pnpm exec vitest run — 6 files, 20 tests passed (3 new).
  • pnpm exec tsc --noEmit — clean.
  • pnpm build — passes (local run needs a cuid-shaped NEXT_PUBLIC_PRIVY_APP_ID; unrelated to this change).

Preview verification to follow in a PR comment.

🤖 Generated with Claude Code


Summary by cubic

Adds custom analytics events to measure pricing CTAs and the valuation funnel using @vercel/analytics. Implements a safe trackEvent wrapper and wires five events to meet Linear 1902 (M3) marketing analytics goals.

  • New Features
    • trackEvent wrapper around @vercel/analytics track; swallows errors; unit tests added.
    • Events: pricing_cta_clicked (plan id), valuation_artist_selected (artist_name), valuation_run, valuation_completed (tracks_measured, duration_ms), open_app_clicked.

Written for commit 361cdef. Summary will update on new commits.

Review in cubic

recoupable.dev had @vercel/analytics mounted but emitted zero custom
events, so the marketing funnel was unmeasurable. Adds a thin, tested
trackEvent wrapper (swallows errors so analytics can never break the
page) and wires five funnel events: pricing_cta_clicked (per plan),
valuation_artist_selected, valuation_run, valuation_completed
(tracks_measured + duration_ms), and open_app_clicked. Purely additive:
no hrefs, copy, or styling change.

Part of recoupable/chat#1902 (M3).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marketing Ready Ready Preview Jul 29, 2026 3:03pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sweetmantech, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 58 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cfeea7ae-efe9-4a45-9c6e-6f9a0fca1a09

📥 Commits

Reviewing files that changed from the base of the PR and between e1a67c7 and 361cdef.

📒 Files selected for processing (8)
  • app/pricing/page.tsx
  • components/layout/HeaderAuthActions.tsx
  • components/layout/HeaderMobileAuthLinks.tsx
  • components/pricing/PricingCtaLink.tsx
  • components/valuation/CatalogValuation.tsx
  • hooks/useCatalogValuation.ts
  • lib/analytics/__tests__/trackEvent.test.ts
  • lib/analytics/trackEvent.ts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 8 files

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant