Skip to content

Growth: fix the two funnel leaks (cold-start + viral loop) + paste/error hardening#1

Merged
alexandermayes merged 3 commits into
mainfrom
growth/viral-loop-and-demo
Jul 17, 2026
Merged

Growth: fix the two funnel leaks (cold-start + viral loop) + paste/error hardening#1
alexandermayes merged 3 commits into
mainfrom
growth/viral-loop-and-demo

Conversation

@alexandermayes

@alexandermayes alexandermayes commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Shippable growth changes from the PostHog funnel analysis. The product core is healthy (98.5% analysis / 96% engaged); the funnel leaks at two points, which these changes target:

  • Visitor → submit: 47.6% — over half bounce before running anything.
  • Share rate: 2.8% — the viral loop is nearly dead; inbound Discord/social referral traffic is ~zero to match.

Acquisition mix (30d): Direct 735 · Google 631 · Reddit ~73 · Bing 67 · ChatGPT 41. SEO is the engine; the viral + SEO items below compound with it.

Changes

1. Discord shares link back (viral loop)

ComparisonSummary.tsx — "Copy for Discord" now appends Full breakdown → <live report URL>, deep-linking to the exact player/fight and letting Discord unfurl the OG scorecard. Adds discord_copied.has_link.

2. "See a live example" on the landing page (cold-start)

lib/demo-report.ts (new) + ReportUrlForm.tsx — a "Don't have a log handy? See a live example →" button deep-links to a verified-public raid so first-time visitors without a log URL can experience the product. Fires demo_report_clicked. Featured report is a single swappable constant.

3. Promote + ungate sharing

AnalyzeClient.tsx — header Share button goes outline → filled; adds a "Share it with your guild" CTA at the bottom of every tab (was only surfaced in the player scorecard).

4. Paste friction + private-report instrumentation

url-parser.ts — extracts a /reports/<code> from pasted text with surrounding words (mobile/Discord shares) and reads fight/source from both #hash and ?query styles (targets the 14% mobile invalid rate). AnalyzeClient.tsx — fires report_load_failed on private/failed loads (previously silent) and clearer error copy for private logs.

Measurement (PostHog insights)

Notes

  • Not build-verified locally (no node on PATH in the authoring env) — please confirm npm run build in CI/preview.
  • New events to add to PostHog if you track a schema: demo_report_clicked, report_load_failed, discord_copied.has_link.
  • Still open (separate, larger PR): make report pages indexable + SSR a summary — the big SEO compounder that feeds the Google channel.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i

@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
parseforge Ready Ready Preview, Comment Jul 16, 2026 8:09pm

@alexandermayes alexandermayes changed the title Growth: viral backlink in Discord copy + landing-page demo report Growth: fix the two funnel leaks (cold-start + viral loop) + paste/error hardening Jul 16, 2026
alexandermayes added a commit that referenced this pull request Jul 16, 2026
The biggest SEO lever from the funnel analysis: ~1,500 analyses/mo
generated zero organic search value because analyze pages were
noindex + fully client-rendered, while Google is already the #1
acquisition channel.

- lib/report-meta.ts: cached (React cache) server fetch returning a
  discriminated result (ok/private/not_found/error); shares mapReportMeta
  with the API route so the mapping lives in one place.
- page.tsx: real per-report <title>/description/OG from the actual report
  (was "Report ABC123"); index ONLY when the report loads publicly;
  canonical without query params folds ?fight=&source= variants; deleted
  reports return a real 404; private/errored stay noindex.
- ReportSummary.tsx: server-rendered, crawlable summary (headline, zone,
  encounter list, roster) below the unchanged interactive app.

Safeguards keep the ephemeral-content risk contained: private → noindex,
deleted → 404, transient WCL errors → noindex + client retry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i
alexandermayes and others added 3 commits July 16, 2026 15:36
Growth changes from the PostHog funnel analysis (2.8% share rate,
47.6% visitor→submit):

- ComparisonSummary: "Copy for Discord" now appends a deep link back to
  the report so shares drive inbound traffic and Discord unfurls the OG
  scorecard image. Adds discord_copied.has_link for measurement.
- ReportUrlForm + lib/demo-report.ts: landing page gains a "See a live
  example" button targeting visitors who arrive without a log URL handy
  (the ~52% who bounce before submitting). Fires demo_report_clicked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i
Lifts the 2.8% share rate found in the funnel analysis:
- Header "Share" button goes from outline to filled (default) so it's
  discoverable, not a faint top-right icon.
- Adds a "Found this useful? Share it with your guild" CTA at the bottom
  of every tab (raid/player/CLA), where users finish reading — sharing
  was previously only surfaced in the player scorecard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i
Targets the higher mobile invalid-URL rate (14% vs 11% desktop) and a
blind spot found in the funnel analysis:

- url-parser: extract a /reports/<code> from pasted text that includes
  surrounding words (mobile/Discord shares), and read fight/source from
  both #hash and ?query styles. Fully backward-compatible.
- AnalyzeClient: fire report_load_failed when a report passes validation
  but won't load (usually a private log) — previously a silent drop-off.
- Clearer error copy telling users to set a private log to Public/Unlisted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i
@alexandermayes
alexandermayes force-pushed the growth/viral-loop-and-demo branch from 453d62e to 9ef6545 Compare July 16, 2026 22:36
@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

The provided GitHub repository does not contain the requested branch or commit reference. Please ensure the repository is not empty.

@alexandermayes
alexandermayes merged commit 013428b into main Jul 17, 2026
1 of 2 checks passed
@alexandermayes
alexandermayes deleted the growth/viral-loop-and-demo branch July 17, 2026 18:13
alexandermayes added a commit that referenced this pull request Jul 17, 2026
…#2)

* SSR public report summaries + make them indexable

The biggest SEO lever from the funnel analysis: ~1,500 analyses/mo
generated zero organic search value because analyze pages were
noindex + fully client-rendered, while Google is already the #1
acquisition channel.

- lib/report-meta.ts: cached (React cache) server fetch returning a
  discriminated result (ok/private/not_found/error); shares mapReportMeta
  with the API route so the mapping lives in one place.
- page.tsx: real per-report <title>/description/OG from the actual report
  (was "Report ABC123"); index ONLY when the report loads publicly;
  canonical without query params folds ?fight=&source= variants; deleted
  reports return a real 404; private/errored stay noindex.
- ReportSummary.tsx: server-rendered, crawlable summary (headline, zone,
  encounter list, roster) below the unchanged interactive app.

Safeguards keep the ephemeral-content risk contained: private → noindex,
deleted → 404, transient WCL errors → noindex + client retry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i

* Self-populating report sitemap + richer SSR summary

- kv-cache: recordRecentReport/getRecentReports back a Redis sorted set of
  public report codes (scored by last render). No new dependency; no-ops
  when shared Redis is absent (local dev).
- report-meta: record each public report when it server-renders.
- sitemap: emit the most recent public reports (hourly revalidate) so Google
  actively crawls them, alongside the static homepage + guides.
- ReportSummary: add an at-a-glance stat row (encounters, kills, raiders,
  combat time) to the crawlable summary.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TG7Bgzws6wZi3hA1P8Gs2i

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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