Problem
The marketing site pricing page's "Go Pro" CTA links to 3dstreet.app/#payment-pro. On app load, firstModal() in src/store.js opens the payment modal directly from that hash — but:
- No
modal_opened event fires for hash-opened payment modals (the paywall path via startCheckout() does fire one).
EditorUpgradeModal.jsx passes source={postCheckout || 'editor'}. Deep-link entry never sets postCheckout, so checkout_started and downstream payment_completed report source=editor.
Result: pricing-page conversions are indistinguishable from generic in-editor upgrades in PostHog. A recent verified conversion trail confirmed this — the user entered via #payment-pro and the funnel recorded checkout_started source=editor. We can't measure our highest-intent acquisition surface (the marketing pricing page) at all.
Proposed fix
EditorUpgradeModal already parses the payment hash once at mount (parsePaymentHash). Extend that to record whether the mount hash was a payment deep link, and pass it through:
source='payment_deeplink' (or similar) instead of the 'editor' fallback when the modal was opened by the hash
- keep the existing tier/cycle parsing unchanged
- optionally fire
modal_opened { modal: 'payment', source: 'payment_deeplink' } on hash-open for funnel completeness
Note the deep link is consumed on close/success (consumeDeepLink), so the source flag should follow the same lifecycle — a later in-session paywall trigger must not inherit the deeplink attribution.
Files
src/editor/components/EditorUpgradeModal.jsx (source prop, ~line 143; parsePaymentHash)
src/store.js (firstModal() hash handling)
src/shared/components/UpgradeModal/UpgradeModal.jsx (checkout_started capture, ~line 163)
- Pricing CTA that emits the link: 3dstreet-docs
src/pages/pricing.js
🤖 Generated with Claude Code
Problem
The marketing site pricing page's "Go Pro" CTA links to
3dstreet.app/#payment-pro. On app load,firstModal()insrc/store.jsopens the payment modal directly from that hash — but:modal_openedevent fires for hash-opened payment modals (the paywall path viastartCheckout()does fire one).EditorUpgradeModal.jsxpassessource={postCheckout || 'editor'}. Deep-link entry never setspostCheckout, socheckout_startedand downstreampayment_completedreportsource=editor.Result: pricing-page conversions are indistinguishable from generic in-editor upgrades in PostHog. A recent verified conversion trail confirmed this — the user entered via
#payment-proand the funnel recordedcheckout_started source=editor. We can't measure our highest-intent acquisition surface (the marketing pricing page) at all.Proposed fix
EditorUpgradeModalalready parses the payment hash once at mount (parsePaymentHash). Extend that to record whether the mount hash was a payment deep link, and pass it through:source='payment_deeplink'(or similar) instead of the'editor'fallback when the modal was opened by the hashmodal_opened { modal: 'payment', source: 'payment_deeplink' }on hash-open for funnel completenessNote the deep link is consumed on close/success (
consumeDeepLink), so the source flag should follow the same lifecycle — a later in-session paywall trigger must not inherit the deeplink attribution.Files
src/editor/components/EditorUpgradeModal.jsx(source prop, ~line 143;parsePaymentHash)src/store.js(firstModal()hash handling)src/shared/components/UpgradeModal/UpgradeModal.jsx(checkout_startedcapture, ~line 163)src/pages/pricing.js🤖 Generated with Claude Code