feat(pro): cut /pro over from waitlist → Pro-launched messaging#3149
Conversation
Pro is live. The landing page and the dashboard's header banner still treated it as a coming-soon waitlist — hero was an email capture form behind Turnstile, nav CTA said "Reserve Your Early Access", and the dashboard banner said "Pro is coming / Reserve your spot". All of that funneled traffic into a waitlist instead of the now-working pricing + checkout + Clerk sign-in flow. Dashboard (/) — src/components/ProBanner.ts: - "Pro is coming" → "Pro is launched" - "Reserve your spot →" (href /pro) → "Upgrade to Pro →" (href /pro#pricing) - Re-enable dismiss button (commented out during launch-promotion period) Landing page (/pro) — pro-test/src/App.tsx + main.tsx + index.html: - Navbar: single "Reserve Your Early Access" → two CTAs: "Sign In" (opens Clerk) + "Upgrade to Pro" (anchors #pricing) - Hero: drop the email + Turnstile + Mailcheck waitlist form, the "Launching March 2026" line, and the referral-invite banner. Replace with "Choose Your Plan" (→ #pricing) + "Sign In" buttons. - Two-path split Pro card: "Reserve Your Early Access" → "Choose Your Plan" (already anchors #pricing) - Footer: drop the second waitlist form + finalCta block + #waitlist anchor. Keep the nav/legal strip only. - Rip dead code: submitWaitlist, showReferralSuccess, Mailcheck import and React hook state. Keep Turnstile infrastructure because the enterprise contact form (#enterprise-contact) still uses it. - JSON-LD Offer: "Pro (Waitlist)" @ $0 → "Pro" @ $39.99. Rebuild the /pro bundle (same committed-artifact dance as PR #3148): grep for the old gate + waitlist strings in the new bundle returns 0. i18n: added nav.signIn, nav.upgradeToPro, hero.choosePlan, hero.signIn, twoPath.choosePlan. Stale waitlist keys left in place — other locales fall back to English until the full sweep.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Resolves the followup from the previous cutover commit: no more silent
English fallback for signIn / upgradeToPro / choosePlan strings in
non-English /pro pages.
Touched keys per locale:
nav.signIn, nav.upgradeToPro (both added — nav block existed)
hero.signIn, hero.choosePlan (both added — hero block existed)
twoPath.choosePlan (added — most locales had no twoPath
block at all, so it's created with
just this one key; remaining twoPath
strings still fall back to English,
which is the pre-existing state)
Covers: ar, bg, cs, de, el, es, fr, it, ja, ko, nl, pl, pt, ro, ru,
sv, th, tr, vi, zh.
Rebuilt the /pro bundle so the per-locale lazy chunks under
public/pro/assets/{lang}-*.js ship the new strings. Verified via grep
for translated strings (e.g. "升级到 Pro", "Passer à Pro",
"الترقية إلى") in the rebuilt locale chunks.
Greptile SummaryThis PR cuts over the
Confidence Score: 4/5Safe to merge with the SEO prerender h1 addressed; all other findings are style/UX suggestions. One P1 defect in the committed build artifact (undefined h1 in the hidden SEO prerender) that could affect search rankings; the two P2s (footer padding, dismiss key) are non-blocking. Functional behavior — sign-in flow, pricing anchor links, Turnstile for enterprise form, banner dismiss — all look correct. public/pro/index.html — SEO prerender h1 is 'undefined undefined'; needs a clean rebuild or a manual fix to the static prerender template. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User visits /pro] --> B{JS loaded?}
B -- No --> C[noscript fallback HTML]
B -- Yes --> D[React App mounts]
D --> E{Hash starts with enterprise?}
E -- Yes --> F[EnterprisePage rendered]
E -- No --> G[Main Landing Page]
G --> H[Navbar: Sign In + Upgrade to Pro]
G --> I[Hero: Choose Your Plan + Sign In]
G --> J[PricingSection anchor]
H -->|openSignIn click| K[ensureClerk openSignIn]
I -->|openSignIn click| K
I -->|pricing anchor| J
L[User visits dashboard] --> M[showProBanner]
M --> N{dismissed in localStorage?}
N -- No --> O[Show Pro is launched banner]
N -- Yes within 7d --> P[Banner hidden]
O -->|Dismiss click| Q[Store timestamp in localStorage]
O -->|CTA click| R[Navigate to pro pricing]
|
| <footer className="border-t border-wm-border bg-[#020202] pt-24 pb-12 px-6 text-center"> | ||
| <div className="flex flex-col md:flex-row items-center justify-between max-w-7xl mx-auto pt-8 border-t border-wm-border/50 text-xs text-wm-muted font-mono"> |
There was a problem hiding this comment.
Footer
pt-24 left over from removed finalCta block
The finalCta section was removed from the footer in this PR, but the pt-24 (96 px) top padding was kept. With no content above the nav/legal strip, the footer now renders a large blank space before the links. Consider reducing to pt-8 or pt-12.
| <footer className="border-t border-wm-border bg-[#020202] pt-24 pb-12 px-6 text-center"> | |
| <div className="flex flex-col md:flex-row items-center justify-between max-w-7xl mx-auto pt-8 border-t border-wm-border/50 text-xs text-wm-muted font-mono"> | |
| <footer className="border-t border-wm-border bg-[#020202] pt-8 pb-12 px-6 text-center"> |
| let bannerEl: HTMLElement | null = null; | ||
|
|
||
| /* TODO: re-enable dismiss after pro launch promotion period | ||
| const DISMISS_KEY = 'wm-pro-banner-dismissed'; |
There was a problem hiding this comment.
Dismiss key reuse silences the new launch banner for recent dismissers
DISMISS_KEY is unchanged from the waitlist era. Any user who dismissed the "Pro is coming" banner in the last 7 days will have an unexpired wm-pro-banner-dismissed timestamp in localStorage and will never see the "Pro is launched" messaging during that window. Consider bumping the key (e.g. wm-pro-banner-v2-dismissed) so the new launch message is shown once to everyone.
…uppressed Reviewer on #3149 flagged that re-enabling dismissal with the same wm-pro-banner-dismissed key carries forward any dismissal from the pre-launch "Pro is coming / Reserve your spot" banner. Anyone whose localStorage still holds that key (e.g. dismissed during the brief March 9 to March 11 window before #1422 disabled dismissal) would silently suppress the new "Pro is launched / Upgrade to Pro" banner and never see the launch CTA. Rename DISMISS_KEY to wm-pro-banner-launched-dismissed (semantically scoped to the launched-state variant) and clear the legacy key on every isDismissed() call so stale entries don't accumulate. Dark / light rendering and the 7-day TTL behavior are unchanged.
…over # Conflicts: # public/pro/assets/index-9CL2yigL.js # public/pro/assets/index-CCmKn0uE.js # public/pro/assets/index-c_645qQx.js # public/pro/index.html
Greptile on #3149 flagged that dropping the finalCta block left the footer with pt-24 (96px) top padding above the legal strip, rendering a large blank band. Pare the outer padding down to pt-8 and drop the inner pt-8 + border-wm-border/50 divider (which only existed to separate the legal strip from the removed finalCta content above). Rebuilt /pro bundle accordingly.
Summary
Pro is live. The landing page and the dashboard's header banner still treated it as a coming-soon waitlist — hero was an email capture behind Turnstile, nav CTA said "Reserve Your Early Access", and the dashboard banner said "Pro is coming / Reserve your spot." All of that funneled traffic into a waitlist instead of the now-working pricing + checkout + Clerk sign-in flow.
Dashboard (
/) —src/components/ProBanner.tsLanding page (
/pro) —pro-test/Rebuild step
Same committed-artifact dance as PR #3148 — ran `npm run build` in `pro-test/`. New asset hashes in `public/pro/assets/`, `public/pro/index.html` rewired.
Verification:
```
$ grep -c 'wm-widget-key\|wm-pro-key\|submitWaitlist\|pro-waitlist' public/pro/assets/index-*.js
0
$ grep -oE '.{10}(Upgrade to Pro|Choose Your Plan|Sign In).{10}' public/pro/assets/index-*.js | head -3
ess:"Reserve Your Early Access",signIn:"Sign In",upgradeToPro:"Upgr
Email address for waitlist",choosePlan:"Choose Your Plan",signIn:"Sign In"},
"Reserve Your Early Access",choosePlan:"Choose Your Plan",entTitle:"World Mo
```
i18n
New keys in `pro-test/src/locales/en.json`: `nav.signIn`, `nav.upgradeToPro`, `hero.choosePlan`, `hero.signIn`, `twoPath.choosePlan`. Stale waitlist keys (`reserveAccess`, `reserveEarlyAccess`, `launchingDate`, `proCta`, etc.) are now unused by code but left in locale files — other locales fall back to English until a translation sweep.
Out of scope / follow-ups
Test plan